5

Tôi đang thiết kế một API RESTful cho một ứng dụng di động mà tôi đang làm việc. Vấn đề của tôi là với các bộ sưu tập lớn chứa nhiều mục. Tôi hiểu rằng thực hành tốt là phân trang số lượng lớn các kết quả trong một bộ sưu tập.Vấn đề về số trang trong thiết kế RESTful API

Tôi đã đọc tài liệu API biểu đồ Facebook (https://developers.facebook.com/docs/graph-api/using-graph-api/v2.2), tài liệu con trỏ Twitter (https://dev.twitter.com/overview/api/cursoring), GitHub API doc (https://developer.github.com/v3/) và bài đăng này (API pagination best practices).

Hãy xem xét một bộ sưu tập mẫu /resources trong API của tôi có chứa 100 mục có tên resource1 đến resource100 và được sắp xếp giảm dần. Đây là câu trả lời bạn sẽ nhận được khi một yêu cầu GET (GET http://api.path.com/resources?limit=5):

{ 
    "_links": { 
     "self": { "href": "/resources?limit=5&page=1" }, 
     "last": { "href": "/resources?limit=5&page=7" }, 
     "next": { "href": "/resources?limit=5&page=2" } 
    }, 

    "_embedded": { 
     "records": [ 
      { resource 100 }, 
      { resource 99 }, 
      { resource 98 }, 
      { resource 97 }, 
      { resource 96 } 
     ] 
    } 
} 

Bây giờ vấn đề của tôi là một kịch bản như thế này:

1- Tôi GET /resources với nội dung trên.

2- Sau đó, nội dung nào đó được thêm vào bộ sưu tập tài nguyên (giả sử một thiết bị khác thêm tài nguyên mới cho tài khoản này). Bây giờ tôi có 101 tài nguyên.

3- Tôi nhận được /resources?limit=5&page=2 vì phản hồi ban đầu cho thấy sẽ chứa trang tiếp theo trong kết quả của tôi. Câu trả lời sẽ là như thế này:

{ 
    "_links": { 
     "self": { "href": "/history?page=2&limit=5" }, 
     "last": { "href": "/history?page=7&limit=5" }, 
     "next": { "href": "/history?page=3&limit=5" } 
    }, 

    "_embedded": { 
     "records": [ 
      { resource 96 }, 
      { resource 95 }, 
      { resource 94 }, 
      { resource 93 }, 
      { resource 92 } 
     ] 
    } 
} 

Như bạn thấy resource 96 được lặp lại trong cả hai trang (Hoặc vấn đề tương tự có thể xảy ra nếu một nguồn lực bị xóa trong bước 2, trong trường hợp đó một tài nguyên sẽ bị mất).

Vì tôi muốn sử dụng ứng dụng này trong ứng dụng dành cho thiết bị di động và trong một danh sách, tôi phải thêm tài nguyên của từng cuộc gọi API vào một cuộc gọi trước đó để tôi có thể có danh sách đầy đủ. Nhưng điều này thật rắc rối. Vui lòng cho tôi biết nếu bạn có đề xuất. Cảm ơn bạn trước.

P.S: Tôi đã coi dấu thời gian như chuỗi truy vấn thay vì phân trang dựa trên con trỏ, nhưng điều đó sẽ gây ra vấn đề ở một nơi khác cho tôi. (cho tôi biết nếu bạn cần thêm thông tin về điều đó.)

+0

Tại sao không sử dụng cả phân trang dựa trên con trỏ và dấu thời gian? –

Trả lời

0

Tại sao không chỉ duy trì một bộ tài nguyên đã xem?

Sau đó, khi bạn xử lý từng câu trả lời, bạn có thể kiểm tra xem tài nguyên đã được trình bày chưa.

+0

Điều đó sẽ chỉ ngăn chặn điều gì đó lặp lại trong chế độ xem, nhưng ở cấp độ thấp hơn, tôi lãng phí thời gian thực hiện các cuộc gọi API không nhận được tôi những gì tôi muốn. (Hình ảnh bước 2 của tôi nếu thêm 20 tài nguyên) – Mepla

3

Chúng tôi vừa triển khai một cái gì đó tương tự như thế này cho một ứng dụng dành cho thiết bị di động thông qua API REST. Ứng dụng dành cho thiết bị di động đã chuyển thông số truy vấn bổ sung đại diện cho dấu thời gian mà tại đó các phần tử trong trang sẽ bị "cố định".

Vì vậy, yêu cầu đầu tiên của bạn sẽ trông giống như GET /resources?limit=5&page=1&from=2015-01-25T05:10:31.000Z và sau đó yêu cầu trang thứ hai (một thời gian sau đó) sẽ làm tăng số lần trang nhưng giữ dấu thời gian như nhau: GET /resources?limit=5&page=2&from=2015-01-25T05:10:31.000Z

này cũng cung cấp cho các kiểm soát ứng dụng di động nếu muốn để phân biệt trang "mềm" (giữ lại dấu thời gian của yêu cầu trang 1) từ trang "làm mới cứng" (đặt lại dấu thời gian cho thời gian hiện tại).

+0

Cảm ơn bạn rất nhiều vì đã trả lời. Có, tôi đang xem xét cách tiếp cận đó nhưng như tôi đã nói trong P.S có thể gây ra nhiều vấn đề hơn cho tôi. Dù sao nếu tôi kết thúc bằng cách sử dụng giải pháp này, tôi sẽ đánh dấu câu trả lời của bạn là được chấp nhận. Cảm ơn một lần nữa. – Mepla

+0

Vâng tôi đã kết thúc làm cả hai curser dựa và một dấu thời gian trước/sau. Thêm điều này vào câu trả lời của bạn và tôi sẽ chấp nhận nó. Cảm ơn bạn rất nhiều :) – Mepla

+0

Ngoại trừ việc tôi không hiểu tại sao bạn sử dụng cả dấu thời gian trước và sau dấu thời gian cho mỗi yêu cầu, bạn cũng không giải thích tại sao chỉ sử dụng một dấu thời gian sẽ gây ra sự cố. –

Các vấn đề liên quan