Skip to content

"fields" query param logic

maxceem edited this page May 6, 2021 · 9 revisions

Background

Some models have one to many relations to other models, see Data Model.

For example one Resource Booking record can have multiple Work Periods. When we call endpoint GET /resourceBookings we are getting a list of Resource Bookings which looks like this:

[
    {
        "id": "dc4477ec-07f8-4c8e-a8fe-ffe38dd290fa",
        "projectId": 111,
        "userId": "e5e667ad-0950-43c2-8d1d-6e83ad7d1c7e",
        "jobId": "2d5e2a52-e0dd-4cd9-8f4c-7cffa43951d0",
        // ... all other fields
    },
    {
        "id": "d38a6223-3f91-4300-9ecb-6e5fee173625",
        "projectId": 111,
        "userId": "39c7376e-2d5c-4601-bc47-6b60f505814d",
        "jobId": "2d5e2a52-e0dd-4cd9-8f4c-7cffa43951d0",
        // ... all other fields
    },
    // ... other records
]

But we might be interested in getting a list of corresponding Work Periods inside Resource Bookings records like this:

[
    {
        "id": "dc4477ec-07f8-4c8e-a8fe-ffe38dd290fa",
        "projectId": 111,
        "userId": "e5e667ad-0950-43c2-8d1d-6e83ad7d1c7e",
        "jobId": "2d5e2a52-e0dd-4cd9-8f4c-7cffa43951d0",
        // ... all other fields
        "workPeriods": [
             {
                 "startDate": "2021-01-01",
                 "endDate": "2021-01-07"
                 // ... all other fields
             },
             {
                 "startDate": "2021-01-08",
                 "endDate": "2021-01-15"
                 // ... all other fields
             },
             // ... other Work Period records
        ]
    },
    {
        "id": "d38a6223-3f91-4300-9ecb-6e5fee173625",
        "projectId": 111,
        "userId": "39c7376e-2d5c-4601-bc47-6b60f505814d",
        "jobId": "2d5e2a52-e0dd-4cd9-8f4c-7cffa43951d0",
        // ... all other fields
        "workPeriods": [
             {
                 "startDate": "2021-01-01",
                 "endDate": "2021-01-07"
                 // ... all other fields
             },
             {
                 "startDate": "2021-01-08",
                 "endDate": "2021-01-15"
                 // ... all other fields
             },
             // ... other Work Period records
        ]
    },
    // ... other records
]

Though as we not always want to get such nested data we would like to keep this optional.

Solution Logic

Endpoints for getting a list of records (like GET /resourceBookings) or individual records (like GET /resourceBookings/:id) might support fields query param with the next logic:

  • If fields query params is not defined, then we by default we return all the fields from the main model.

  • If fields query param is defined, then we return only the fields listed in this query param. For example: fields=id,projectId should only return records with fields id and projectId like this:

    [
        {
            "id": "dc4477ec-07f8-4c8e-a8fe-ffe38dd290fa",
            "projectId": 111,
        },
        {
            "id": "d38a6223-3f91-4300-9ecb-6e5fee173625",
            "projectId": 111
        },
        // ... other records
    ]
  • To return nested model records we have to explicitly list it in the fields list. For example: fields=id,projectId,workPeriods should only return records with fields id and projectId and workPeriods field with the list of associated Work Periods:

    [
        {
            "id": "dc4477ec-07f8-4c8e-a8fe-ffe38dd290fa",
            "projectId": 111,
            "workPeriods": [
                {
                    "id": "57646ff9-1cd3-4d3c-88ba-eb09a395366c",
                    "startDate": "2021-01-01",
                    "endDate": "2021-01-07"
                    // ... all other fields of Work Period record
                },
                {
                    "id": "2d5e2a52-e0dd-4cd9-8f4c-7cffa43951d0",
                    "startDate": "2021-01-08",
                    "endDate": "2021-01-15"
                    // ... all other fields of Work Period record
                },
                // ... other Work Period records
            ]
        },
        {
            "id": "d38a6223-3f91-4300-9ecb-6e5fee173625",
            "projectId": 111,
            "workPeriods": [
                {
                    "id": "57646ff9-1cd3-4d3c-88ba-eb09a395366d",
                    "startDate": "2021-03-04",
                    "endDate": "2021-03-10"
                    // ... all other fields of Work Period record
                },
                {
                    "id": "2d5e2a52-e0dd-4cd9-8f4c-7cffa43951d1",
                    "startDate": "2021-03-11",
                    "endDate": "2021-03-17"
                    // ... all other fields of Work Period record
                },
                // ... other Work Period records
            ]
        },
        // ... other Resource Bookings records
    ]
  • We should be also able to return only specific fields from the nested model like Work Periods, by listing the particular fields like this: fields=id,projectId,workPeriods.id,workPeriods.startDate would only return id and projectId from the main model, plus id and startDate for the nested Work Periods records:

    [
        {
            "id": "dc4477ec-07f8-4c8e-a8fe-ffe38dd290fa",
            "projectId": 111,
            "workPeriods": [
                {
                    "id": "57646ff9-1cd3-4d3c-88ba-eb09a395366c",
                    "startDate": "2021-01-01"
                },
                {
                    "id": "2d5e2a52-e0dd-4cd9-8f4c-7cffa43951d0"                    
                     "startDate": "2021-01-08"
                },
                // ... other Work Period records
            ]
        },
        {
            "id": "d38a6223-3f91-4300-9ecb-6e5fee173625",
            "projectId": 111,
            "workPeriods": [
                {
                    "id": "57646ff9-1cd3-4d3c-88ba-eb09a395366d",
                    "startDate": "2021-03-04"
                },
                {
                    "id": "2d5e2a52-e0dd-4cd9-8f4c-7cffa43951d1",                   
                    "startDate": "2021-03-11"
                },
                // ... other Work Period records
            ]
        },
        // ... other Resource Bookings records
    ]
Clone this wiki locally