What is OData standard for odata.nextLink in case of 1:N $expand queries?

Viewed 113

We can see the odata.nextlink standard in the server driven paging for normal queries here. But there is no odata.nextlink standard mentioned in case of 1:N $expand queries in $expand docs.

Can someone please confirm OData standard for 1:N $expand queries please?

Example: If we have multiple account_tasks for a single account, how the result should look like:

GET [Organization URI]/api/data/v9.1/accounts?$top=1&$expand=Account_Tasks($select=subject)

Option-1: Where data is shown in list inline till the page-size, and odata.nextLink is shown if data count exceeds the page-size. So, odata.nextLink will show the next set of results. (Similar to standard pagination here.)

{
    "@odata.context": "[Organization URI]/api/data/v9.1/$metadata#accounts(name,Account_Tasks(subject,scheduledstart))",
    "value": [
        {
            "@odata.etag": "W/\"37867294\"",
            "name": "Contoso, Ltd. (sample)",
            "accountid": "7a4814f9-b0b8-ea11-a812-000d3a122b89",
            "Account_Tasks": [
                {
                    "@odata.etag": "W/\"28876919\"",
                    "subject": "Task 1 for Contoso, Ltd.",
                },
                {
                   // More account_tasks here. No odata.nextLink if data count < page-size.
            ]
        }
    ] 
 }

Option-2: We'll show empty results inline and provide an odata.nextLink to actual data.

{
    "@odata.context": "[Organization URI]/api/data/v9.1/$metadata#accounts(name,Account_Tasks(subject,scheduledstart))",
    "value": [
        {
            "@odata.etag": "W/\"37867294\"",
            "name": "Contoso, Ltd. (sample)",
            "accountid": "7a4814f9-b0b8-ea11-a812-000d3a122b89",
            "Account_Tasks": [], 
             // Empty list shown above and URL given below will show the full results.
            "Account_Tasks@odata.nextLink": "[Organization URI]/api/data/v9.1/accounts(7a4814f9-b0b8-ea11-a812-000d3a122b89)/Account_Tasks?$select=subject,scheduledstart"
        }
    ] 
 }

Option-3: Where data is shown in list till page-size, and odata.nextLink is shown every time (even if data count is smaller than the page-size). So, the odata.nextLink will show the full expand results including inline results.

{
    "@odata.context": "[Organization URI]/api/data/v9.1/$metadata#accounts(name,Account_Tasks(subject,scheduledstart))",
    "value": [
        {
            "@odata.etag": "W/\"37867294\"",
            "name": "Contoso, Ltd. (sample)",
            "accountid": "7a4814f9-b0b8-ea11-a812-000d3a122b89",
            "Account_Tasks": [
                {
                    "@odata.etag": "W/\"28876919\"",
                    "subject": "Task 1 for Contoso, Ltd.",
                },
                {
                   // More account tasks here       
            ],
            "Account_Tasks@odata.nextLink": "[Organization URI]/api/data/v9.1/accounts(7a4814f9-b0b8-ea11-a812-000d3a122b89)/Account_Tasks?$select=subject,scheduledstart"
        }
    ] 
 }

Thanks in advance.

1 Answers

Good question -- paging of nested results is often misunderstood.

Nested results are paged individually, so where the nested account_tasks for a particular account exceeds a sever-defined threshold, the account_tasks up to that threshold are included, along with a nextlink to retrieve the additional account_tasks for that account. Which, I believe, is your Option 1.

Note that, since the threshold is server-defined, it is also valid to have a threshold of 0, and only include a nextlink for the nested account_tasks. However, each account will still have a different nextlink, and following that nextlink will return only those account_tasks for the account in which the nextlink was returned.

Does that make sense?

Related