Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

API pagination best practices

I'd love some some help handling a strange edge case with a paginated API I'm building.

Like many APIs, this one paginates large results. If you query /foos, you'll get 100 results (i.e. foo #1-100), and a link to /foos?page=2 which should return foo #101-200.

Unfortunately, if foo #10 is deleted from the data set before the API consumer makes the next query, /foos?page=2 will offset by 100 and return foos #102-201.

This is a problem for API consumers who are trying to pull all foos - they will not receive foo #101.

What's the best practice to handle this? We'd like to make it as lightweight as possible (i.e. avoiding handling sessions for API requests). Examples from other APIs would be greatly appreciated!

like image 533
2arrs2ells Avatar asked Dec 14 '12 03:12

2arrs2ells


People also ask

Should API have pagination?

API pagination is essential if you're dealing with a lot of data and endpoints. Pagination automatically implies adding order to the query result. The object ID is the default result, but results can be ordered in other ways as well.

How pagination is done in API?

The best way to build API pagination in a safe way is for the API to return a “cursor”, or opaque string, with the list of results. This token is usually called next or next_cursor or starting_after This token can be passed with the next API request to request the next page.

What is REST API pagination?

You can paginate the JSON response that is called from the REST API. The order of the data is retained from page to page. Given the ability to paginate, you can quickly populate tables and make new REST calls every time you go to the next page of the data on the table.


1 Answers

I'm not completely sure how your data is handled, so this may or may not work, but have you considered paginating with a timestamp field?

When you query /foos you get 100 results. Your API should then return something like this (assuming JSON, but if it needs XML the same principles can be followed):

{     "data" : [         {  data item 1 with all relevant fields    },         {  data item 2   },         ...         {  data item 100 }     ],     "paging":  {         "previous":  "http://api.example.com/foo?since=TIMESTAMP1"          "next":  "http://api.example.com/foo?since=TIMESTAMP2"     }  } 

Just a note, only using one timestamp relies on an implicit 'limit' in your results. You may want to add an explicit limit or also use an until property.

The timestamp can be dynamically determined using the last data item in the list. This seems to be more or less how Facebook paginates in its Graph API (scroll down to the bottom to see the pagination links in the format I gave above).

One problem may be if you add a data item, but based on your description it sounds like they would be added to the end (if not, let me know and I'll see if I can improve on this).

like image 170
ramblinjan Avatar answered Sep 20 '22 19:09

ramblinjan