Tôi quan tâm đến việc hiển thị giao diện REST trực tiếp cho các bộ sưu tập tài liệu JSON (nghĩ là CouchDB hoặc Persevere ). Vấn đề tôi gặp phải là làm thế nào để xử lý GET
thao tác trên bộ sưu tập gốc nếu bộ sưu tập lớn.
Như một ví dụ giả vờ tôi đang phơi bày Questions
bảng của StackOverflow trong đó mỗi hàng được hiển thị dưới dạng tài liệu (không nhất thiết phải có một bảng như vậy, chỉ là một ví dụ cụ thể về bộ sưu tập 'tài liệu' khá lớn). Bộ sưu tập sẽ được cung cấp ngay /db/questions
với api CRUD thông thường GET /db/questions/XXX
, PUT /db/questions/XXX
, POST /db/questions
là trong vở kịch. Cách tiêu chuẩn để có được toàn bộ bộ sưu tập là GET /db/questions
nhưng nếu điều đó ngây thơ bỏ từng hàng làm đối tượng JSON, bạn sẽ nhận được một bản tải xuống khá lớn và rất nhiều công việc trên một phần của máy chủ.
Giải pháp là, tất nhiên, phân trang. Dojo đã giải quyết vấn đề này trong JsonRestStore thông qua tiện ích mở rộng thông minh tuân thủ RFC2616 bằng cách sử dụng Range
tiêu đề với một đơn vị phạm vi tùy chỉnh items
. Kết quả là 206 Partial Content
chỉ trả về phạm vi được yêu cầu. Ưu điểm của phương pháp này so với tham số truy vấn là nó để lại chuỗi truy vấn cho ... truy vấn (ví dụ: GET /db/questions/?score>200
hoặc somesuch và có được mã hóa %3E
).
Cách tiếp cận này hoàn toàn bao gồm các hành vi tôi muốn. Vấn đề là RFC 2616 chỉ định rằng trên phản hồi 206 (điểm nhấn của tôi):
Các yêu cầu PHẢI tôi đã bao gồm một tiêu đề lĩnh vực Range ( Phần 14,35 ) cho thấy phạm vi mong muốn, và có thể đã bao gồm một tiêu đề lĩnh vực If-Range ( Phần 14,27 ) để làm cho các điều kiện yêu cầu.
Điều này có ý nghĩa trong bối cảnh sử dụng tiêu chuẩn của tiêu đề nhưng là một vấn đề vì tôi muốn phản hồi 206 là mặc định để xử lý các khách hàng ngây thơ / người ngẫu nhiên khám phá.
Tôi đã đi qua RFC một cách chi tiết để tìm kiếm một giải pháp nhưng không hài lòng với các giải pháp của tôi và quan tâm đến vấn đề của SO về vấn đề này.
Ý tưởng tôi đã có:
- Quay trở lại
200
với mộtContent-Range
tiêu đề! - Tôi không nghĩ rằng điều này là sai, nhưng tôi thích nếu một chỉ báo rõ ràng hơn rằng phản hồi chỉ là Nội dung một phần. - Trả về
400 Range Required
- Không có mã phản hồi 400 đặc biệt cho các tiêu đề bắt buộc, do đó, lỗi mặc định phải được sử dụng và đọc bằng tay. Điều này cũng làm cho việc khám phá thông qua trình duyệt web (hoặc một số khách hàng khác như Resty) trở nên khó khăn hơn. - Sử dụng tham số truy vấn - Cách tiếp cận tiêu chuẩn, nhưng tôi hy vọng sẽ cho phép truy vấn la Persevere và điều này cắt vào không gian tên truy vấn.
- Chỉ cần trở về
206
! - Tôi nghĩ rằng hầu hết khách hàng sẽ không sợ hãi, nhưng tôi không muốn chống lại PHẢI trong RFC - Mở rộng thông số kỹ thuật! Trả về
266 Partial Content
- Hành vi chính xác như 206 nhưng đáp lại yêu cầu KHÔNG PHẢI chứaRange
tiêu đề. Tôi cho rằng 266 đủ cao để tôi không gặp phải các sự cố va chạm và điều đó có ý nghĩa với tôi nhưng tôi không rõ liệu điều này có được coi là cấm kỵ hay không.
Tôi nghĩ rằng đây là một vấn đề khá phổ biến và tôi muốn thấy điều này được thực hiện theo kiểu thực tế để tôi hoặc người khác không phát minh lại bánh xe.
Cách tốt nhất để hiển thị một bộ sưu tập đầy đủ qua HTTP khi bộ sưu tập lớn là gì?
Range = "Range" ":" ranges-specifier
vị trí sau trong tools.ietf.org/html/rfc2616#section-14.35.1 được mô tả đơn thuần là "byte- Range -specifier" phải bắt đầu bằng "byte-unit" được định nghĩa là byte "chuỗi" ".
Content-Range
tiêu đề áp dụng đối với cơ thể (có thể được sử dụng với yêu cầu khi tải lên tập tin lớn vv, hoặc cho phản ứng khi tải). Các Range
tiêu đề được sử dụng để yêu cầu một phạm vi nhất định. Người ta phải trả lời 206
khi Range
tiêu đề được bao gồm trong yêu cầu. Nếu không, phản hồi vẫn có thể bao gồm Content-Range
tiêu đề, nhưng mã phản hồi phải là 200
. Tiêu đề này thực sự có vẻ lý tưởng cho phân trang.