Gần đây tôi đã thực hiện một số nghiên cứu sâu rộng về vấn đề này và các câu hỏi liên quan đến phân trang REST khác và nghĩ rằng nó mang tính xây dựng để thêm một số phát hiện của tôi ở đây. Tôi đang mở rộng câu hỏi một chút để bao gồm những suy nghĩ về phân trang cũng như số lượng vì chúng có liên quan mật thiết với nhau.
Tiêu đề
Siêu dữ liệu phân trang được bao gồm trong phản hồi dưới dạng tiêu đề phản hồi. Lợi ích lớn của phương pháp này là bản thân tải trọng phản hồi chỉ là người yêu cầu dữ liệu thực tế đã yêu cầu. Làm cho việc xử lý phản hồi dễ dàng hơn đối với các khách hàng không quan tâm đến thông tin phân trang.
Có một loạt các tiêu đề (tiêu chuẩn và tùy chỉnh) được sử dụng trong tự nhiên để trả về thông tin liên quan đến phân trang, bao gồm tổng số.
Tổng số X
X-Total-Count: 234
Điều này được sử dụng trong một số API tôi tìm thấy trong tự nhiên. Ngoài ra còn có các gói NPM để thêm hỗ trợ cho tiêu đề này, ví dụ Loopback. Một số bài viết khuyên bạn nên thiết lập tiêu đề này là tốt.
Nó thường được sử dụng kết hợp với Link
tiêu đề, đây là một giải pháp khá tốt để phân trang, nhưng thiếu thông tin tổng số.
Liên kết
Link: </TheBook/chapter2>;
rel="previous"; title*=UTF-8'de'letztes%20Kapitel,
</TheBook/chapter4>;
rel="next"; title*=UTF-8'de'n%c3%a4chstes%20Kapitel
Tôi cảm thấy, từ việc đọc rất nhiều về chủ đề này, rằng sự đồng thuận chung là sử dụng Link
tiêu đề để cung cấp liên kết phân trang cho khách hàng sử dụng rel=next
, rel=previous
v.v. Vấn đề với điều này là nó thiếu thông tin về tổng số hồ sơ có, đó là tại sao nhiều API kết hợp điều này với X-Total-Count
tiêu đề.
Ngoài ra, một số API và ví dụ: tiêu chuẩn JsonApi , sử dụng Link
định dạng, nhưng thêm thông tin vào phong bì phản hồi thay vì tiêu đề. Điều này giúp đơn giản hóa việc truy cập vào siêu dữ liệu (và tạo một nơi để thêm tổng số thông tin) với chi phí tăng độ phức tạp của việc truy cập dữ liệu thực tế (bằng cách thêm một phong bì).
Phạm vi nội dung
Content-Range: items 0-49/234
Được quảng bá bởi một bài viết trên blog có tên Range title, tôi chọn bạn (để phân trang)! . Tác giả làm cho một trường hợp mạnh mẽ để sử dụng Range
và Content-Range
tiêu đề cho phân trang. Khi chúng tôi cẩn thận đọc các RFC về các tiêu đề, chúng ta thấy rằng việc mở rộng ý nghĩa của chúng vượt quá phạm vi của các byte đã thực sự dự đoán của RFC và được phép một cách rõ ràng. Khi được sử dụng trong bối cảnh items
thay vìbytes
, tiêu đề Phạm vi thực sự cung cấp cho chúng ta một cách để cả hai yêu cầu một phạm vi mục nhất định và cho biết phạm vi của tổng kết quả mà các mục phản hồi liên quan đến. Tiêu đề này cũng cung cấp một cách tuyệt vời để hiển thị tổng số. Và nó là một tiêu chuẩn thực sự mà chủ yếu là ánh xạ một-một để phân trang. Nó cũng được sử dụng trong tự nhiên .
Phong bì
Nhiều API, bao gồm một API từ trang web Hỏi & Đáp yêu thích của chúng tôi sử dụng một phong bì , một trình bao bọc xung quanh dữ liệu được sử dụng để thêm thông tin meta về dữ liệu. Ngoài ra, OData và JsonApi các tiêu chuẩn đều sử dụng phong bì phản hồi.
Nhược điểm lớn của điều này (imho) là việc xử lý dữ liệu phản hồi trở nên phức tạp hơn vì dữ liệu thực tế phải được tìm thấy ở đâu đó trong phong bì. Ngoài ra có nhiều định dạng khác nhau cho phong bì đó và bạn phải sử dụng đúng. Người ta nói rằng các phong bì phản hồi từ OData và JsonApi rất khác nhau, với OData trộn trong siêu dữ liệu tại nhiều điểm trong phản hồi.
Điểm cuối riêng biệt
Tôi nghĩ rằng điều này đã được bao phủ đủ trong các câu trả lời khác. Tôi đã không điều tra điều này nhiều vì tôi đồng ý với các ý kiến rằng điều này gây nhầm lẫn vì hiện tại bạn có nhiều loại điểm cuối. Tôi nghĩ rằng nó là tốt nhất nếu mỗi điểm cuối đại diện cho một (bộ sưu tập) tài nguyên.
Suy nghĩ xa hơn
Chúng tôi không chỉ phải truyền đạt thông tin meta phân trang liên quan đến phản hồi mà còn cho phép khách hàng yêu cầu các trang / phạm vi cụ thể. Thật thú vị khi nhìn vào khía cạnh này để kết thúc với một giải pháp mạch lạc. Ở đây chúng ta cũng có thể sử dụng các tiêu đề ( Range
tiêu đề có vẻ rất phù hợp) hoặc các cơ chế khác như tham số truy vấn. Một số người chủ trương xử lý các trang kết quả như nguồn lực riêng biệt, trong đó có thể có ý nghĩa trong một số trường hợp sử dụng (ví dụ /books/231/pages/52
. Tôi đã kết thúc việc lựa chọn một phạm vi hoang dã của các thông số yêu cầu thường xuyên được sử dụng như pagesize
, page[size]
và limit
vân vân ngoài việc hỗ trợ các Range
tiêu đề (và như request parameter cũng).