locked
WCF OData $top with "nextLink" RRS feed

  • Question

  • I'm building a WCF Data Service and I found a strange behaviour when I make a GET with the $top parameter set.

    I was expecting, as I found on many sources on the Internet, that the response would give a "nextLink" in case that there were more items than the specified in the $top parameter... that doesn't occur! Why!? Am I doing something wrong? How can I control the page size on the client side and use the "nextLink" to navigate to the next page?

    If I omit the $top parameter, the server controls the page size and retrieves the "nextLink" parameter... but if I use the $top parameter, server never returns "nextLink"! Is this a bug?

    Best regards,

    Fernando Rocha



    Friday, June 14, 2013 3:42 PM

Answers

  • The $top and $skip were designed for usages where the client doesn't want to download all items, instead it wants a first page and then later, when users makes some action, it may need more ($skip and so on).

    If your client needs to download all the data, then ask for the entity set without $top. Most servers will not return all entities in one shot (as it would be dangerous for them... easy to DoS such a server), instead they will employ the server driven paging and thus include the next link in the response. The client can then follow that link and get all the data eventually.

    I agree that the next link is nice for REST and so on, but the query language ($top, $skip, $expand, $filter and so on) is something different. Nothing in REST alone lets you do that. That said I can see that the server could include the next link even in the $top request response, but honestly it wouldn't help that much.

    Also note that server driven paging always wins. So if the client asks for $top=100, but the server only serves up to 20, then the response to such request will still contain just 20 items and a next link. If the client follows the next link until the end, it will get the first 100 records, but not more (since it asked for $top=100). This is what the CodeProject page you refer to talks about. The MDSN page is similar, although I agree the wording there is a bit confusing.

    Thanks,


    Vitek Karas [MSFT]

    • Marked as answer by FernandoRocha Sunday, June 16, 2013 8:42 PM
    Sunday, June 16, 2013 8:23 PM
    Moderator

All replies

  • This behavior is actually by design. The next link is only used when the server side paging kicks in (since the client would otherwise have no idea that it didn't get all the data). If the client explicitly asks for 10 records via $top=10, then the server responds with 10 items. There's no need to notify the client that there's more data. There are basically two ways to page through the entity set:

    Client-driven paging - the client uses $top and $skip. So for first page it would be $top=10, for second $top=10&$skip=10 and so on.

    Server-drive paging - the client has not tell in this case. The server returns a first page with any number of records (note that it doesn't have to be constant and it doesn't have to be consistent between pages, it's just that most services are like that) and a link to get the next page.

    Thanks,


    Vitek Karas [MSFT]

    Sunday, June 16, 2013 12:43 PM
    Moderator
  • Hi Vitek Karas,

    Just by querying the first 10 items ($top=10) you can't always tell if the server has more items. You may include the parameter "$inlinecount=allpages", to know the total number of items of all pages, and then do some math... but isn't that a little contradictory? You're querying the top 10 items and the server doesn't answer with a nextLink to the next page... but you can request the count of all pages.

    It should always be possible to navigate a full set of data using links replied by a RESTful service. Connectedness via hypermedia links is a very common principle for any RESTful service. If I request a paginated set of data, I should be able to navigate through the rest of the set using a specified next link...

    There is also some web pages documenting that functionality, for instance:

    CodeProject (search for "/Products?$top=100&$inlinecount=allpages&$format=json")

    Microsoft MSDN (search for the "$top" parameter description)

    Doesn't this make sense?

    Best regards,

    Fernando Rocha



    Sunday, June 16, 2013 7:25 PM
  • The $top and $skip were designed for usages where the client doesn't want to download all items, instead it wants a first page and then later, when users makes some action, it may need more ($skip and so on).

    If your client needs to download all the data, then ask for the entity set without $top. Most servers will not return all entities in one shot (as it would be dangerous for them... easy to DoS such a server), instead they will employ the server driven paging and thus include the next link in the response. The client can then follow that link and get all the data eventually.

    I agree that the next link is nice for REST and so on, but the query language ($top, $skip, $expand, $filter and so on) is something different. Nothing in REST alone lets you do that. That said I can see that the server could include the next link even in the $top request response, but honestly it wouldn't help that much.

    Also note that server driven paging always wins. So if the client asks for $top=100, but the server only serves up to 20, then the response to such request will still contain just 20 items and a next link. If the client follows the next link until the end, it will get the first 100 records, but not more (since it asked for $top=100). This is what the CodeProject page you refer to talks about. The MDSN page is similar, although I agree the wording there is a bit confusing.

    Thanks,


    Vitek Karas [MSFT]

    • Marked as answer by FernandoRocha Sunday, June 16, 2013 8:42 PM
    Sunday, June 16, 2013 8:23 PM
    Moderator