Offset Based Pagination (基于偏移量的分頁)
如果返回的內容是靜態(tài)的,或者不用實時返回數據最新的變化,那么可以用這種基于偏移量的分頁。Google Search 和一些論壇用了這種方式:

Offset Based Pagination
查詢時指定條件和頁號即可:
GET https://meta.discourse.org/latest.json?page=2
Cursor Base Pagination (基于游標的分頁)
現在很多場景,查詢結果在用戶瀏覽過程中是變化的,例如微博時間線,用戶看的時候,可能后一頁的某些微博會被刪除,而前一頁又增添了新的微博。這種情況就不適合用 Offset Based Pagination。
Facebook 和 Twitter 都采用了基于游標的分頁方法,舉例如下:
{
"data": [
... Endpoint data is here
],
"paging": {
"cursors": {
"after": "MTAxNTExOTQ1MjAwNzI5NDE=",
"before": "NDMyNzQyODI3OTQw"
},
"previous": "https://graph.facebook.com/me/albums?limit=25&before=NDMyNzQyODI3OTQw"
"next": "https://graph.facebook.com/me/albums?limit=25&after=MTAxNTExOTQ1MjAwNzI5NDE="
}
如上所述,Facebook API 返回的數據,除了當前頁面的業(yè)務數據之外(data),也包含分頁數據(paging):
- Cursors (游標) – 每條記錄都應該有一個唯一且遞增的值作為游標值。
- Count – 我們需要 count 參數,就像基于偏移量的分頁一樣,用于在游標之前或之后過濾有限數量的結果。
- Next URL – 這個值可能是 URL,也可能是其他你自己設定的語義,用來獲取下一頁的數據。如果為空,則可以用來表示沒有后一頁的數據。
- Previous URL –同上,只是用來表示前一頁的數據。
這種方式有以下兩個特點:
- 查詢的結果流可能是動態(tài)變化的,例如: 時間線里出現了新的數據,或者刪除了數據,這些變化都可以在 “前一頁” 或者 “后一頁” 上體現出來。
- Cursor 體現了排序,是持久化的。一般情況下 Cursor 的順序是和時間有關。如果你的實體(例如:微博)可能展現給用戶多種可能的排序(例如:創(chuàng)建時間或者修改時間),那么則需要創(chuàng)建不同的 Cursor。
- 具體實現時,Cursor 可能分別創(chuàng)建自
createAt或者modifiedAt字段。Facebook Relay 用了查詢名稱 + 時間戳 的 Base64 形式來做 Cursor。
- 具體實現時,Cursor 可能分別創(chuàng)建自
一個抽象得更為完整的規(guī)范是 https://facebook.github.io/relay/graphql/connections.htm. 閱讀這篇文章需要 GraphQL 的基礎和一些”圖存儲”的概念,作為備查吧。