Home > database >  RESTful API cursor pagination with total count
RESTful API cursor pagination with total count

Time:01-17

I'm designing a RESTful API, returns result with pagination and total number. Here is my approach

Endpoint

[GET] /items

Parameters

Parameter Description
before_cursor Return results before cursor
after_cursor Return results after cursor
limit Limit of result

Response

{
  "items": [
    ...
  ],
  "pagination": {
    "prev_cursor": string, // cursor before the range, for backward navigation
    "next_cursor": string, // cursor after the range, for forward navigation
    "total": number, // total number of items
    "total_before": number, // item count before prev_cursor helps client positioning
    "total_after": number // item count before next_cursor helps client positioning
  }
}

Example

Raw data

Item_0, Item_1, ... Item_99

Get first page

[GET] /items?limit=10

{
  "items": [item_0, ..., item_9],
  "pagination": {
    "next_cursor": "item_10",
    "total": 100,
    "total_before": 0,
    "total_after": 90
  }
}

Navigate to next page

[GET] /items?limit=10&after_cursor=item_10

{
  "items": [item_10, ..., item_19],
  "pagination": {
    "before_cursor": "item_9",
    "next_cursor": "item_20",
    "total": 100,
    "total_before": 10,
    "total_after": 80
  }
}

Navigate back to previous page

[GET] /items?limit=10&before_cursor=item_9

{
  "items": [item_0, ..., item_9],
  "pagination": {
    "next_cursor": "item_10",
    "total": 100,
    "total_before": 0,
    "total_after": 90
  }
}

Is it a good approach? Or is there a neater way to design API for this requirement?

CodePudding user response:

There are multiple ways to design this endpoint with a rest approach. I found these 2 the best when you need to deal with collections.

Approach 1

GET /items?page=2 & page_size=10

This should return only 10 elements from your resource items and skip the first page (it is up to you to decide if you start your collection with a 0 or with 1)

A response should look like this

Response 1:

[
  item1,
  item2,
  ...
  item10
]

Response Header: RecordCount or X-Total-Count = 530

The total count in this case is included in the headers. Now if the user wants to paginate the next page or the previous they can do the following request:

  • next: GET /items?page=3 & page_size=10
  • previous: GET /items?page=1 & page_size=10

Including this request as part of the payload and trying to comply with Rest for HATEOAS is what I think can be the second approach

Response 2:

{
   TotalCount=530,
   Result:
   [
      item1,
      item2,
      ...
      item10
    ],
    Next: '/items?page=3 & page_size=10'
    Previous: 'GET /items?page=1 & page_size=10'
}

In this case, the total count is included in the response and the items on the result and you build the next and previous URLs

  • Related