Phân trang trong bộ sưu tập nghỉ ngơi


134

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ý GETthao 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 Questionsbả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/questionsvới api CRUD thông thường GET /db/questions/XXX, PUT /db/questions/XXX, POST /db/questionslà trong vở kịch. Cách tiêu chuẩn để có được toàn bộ bộ sưu tập là GET /db/questionsnhư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 Rangetiêu đề với một đơn vị phạm vi tùy chỉnh items. Kết quả là 206 Partial Contentchỉ 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>200hoặ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 200với một Content-Rangetiê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ứa Rangetiê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ì?


21
Wow, đó là một ví dụ tốt về một câu hỏi mà một số suy nghĩ nghiêm túc đã được thực hiện trước đó.
Heiko Rupp

bản sao có thể có của Phân trang trong ứng dụng web REST
rds

1
Theo như cách tiếp cận của Dojo trong việc sử dụng tiêu đề Phạm vi, mặc dù Phạm vi Chấp nhận cho phép mở rộng, từ tất cả những gì tôi có thể nói, EBNF cho Phạm vi không: tools.ietf.org/html/rfc2616#section-14.35.2 . Thông số kỹ thuật chỉ ra Range = "Range" ":" ranges-specifiervị 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" ".
Brett Zamir

2
Các Content-Rangetiê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 Rangetiê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 206khi Rangetiê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-Rangetiê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.
Stijn de Witt

Nhưng bản thân RFC 2616 nói rằng "Việc triển khai HTTP / 1.1 CÓ THỂ bỏ qua các phạm vi được chỉ định bằng cách sử dụng các đơn vị khác." Vì vậy, nó có phải là một thực hành tốt để sử dụng tiêu đề Range cho phân trang? Vì nó có thể làm mất khả năng tương tác.
chetan choulwar

Câu trả lời:


23

Cảm giác ruột của tôi là các tiện ích mở rộng phạm vi HTTP không được thiết kế cho trường hợp sử dụng của bạn và do đó bạn không nên thử. Một phản hồi một phần ngụ ý 206206chỉ phải được gửi nếu khách hàng yêu cầu.

Bạn có thể muốn xem xét một cách tiếp cận khác, chẳng hạn như một cách sử dụng trong Atom (trong đó biểu diễn theo thiết kế có thể là một phần và được trả về với trạng thái 200và các liên kết phân trang có khả năng). Xem RFC 4287RFC 5005 .


14
Việc sử dụng Dojo là hoàn toàn trong spec. Nếu máy chủ không hiểu itemsđơn vị phạm vi, nó sẽ trả lời đầy đủ. Tôi quen thuộc với Atom nhưng đó không phải là giải pháp chung để phân trang. Đây không phải là một giải pháp cho một trường hợp duy nhất, nhiều hơn những gì giải pháp chung nên có. Không phải tất cả các tài liệu / bộ sưu tập đều phù hợp với mô hình Atom và không có lý do gì để buộc nó trừ khi được yêu cầu.
Karl Guertin

1
@KarlGuertin Đồng ý. Quá tệ, đây là câu trả lời được chấp nhận, bởi vì có vẻ như nhiều người trong cộng đồng đang thực sự chấp nhận RangeContent-Rangecho mục đích phân trang.
Stijn de Witt

34

Tôi không thực sự đồng ý với một số bạn. Tôi đã làm việc trong nhiều tuần về các tính năng này cho dịch vụ REST của mình. Những gì tôi đã làm là thực sự đơn giản. Giải pháp của tôi chỉ có ý nghĩa đối với những gì người REST gọi là bộ sưu tập.

Khách hàng PHẢI bao gồm tiêu đề "Phạm vi" để chỉ ra phần nào của bộ sưu tập mà anh ta cần, hoặc nếu không, sẵn sàng xử lý lỗi 413 YÊU CẦU TUYỆT VỜI YÊU CẦU khi bộ sưu tập được yêu cầu quá lớn để có thể truy xuất trong một chuyến đi khứ hồi.

Máy chủ gửi phản hồi NỘI DUNG 206, với tiêu đề Phạm vi Nội dung chỉ định phần nào của tài nguyên đã được gửi và tiêu đề ETag để xác định phiên bản hiện tại của bộ sưu tập. Tôi thường sử dụng một ETag giống như Facebook {last_modification_timestamp} - {resource_id} và tôi cho rằng ETag của một bộ sưu tập là tài nguyên được sửa đổi gần đây nhất.

Để yêu cầu một phần cụ thể của bộ sưu tập, khách hàng PHẢI sử dụng tiêu đề "Phạm vi" và điền vào tiêu đề "Nếu khớp" với ETag của bộ sưu tập thu được từ các yêu cầu được thực hiện trước đó để có được các phần khác của cùng bộ sưu tập. Do đó, máy chủ có thể xác minh rằng bộ sưu tập đã không thay đổi trước khi gửi phần được yêu cầu. Nếu có phiên bản mới hơn tồn tại, phản hồi 412 CHÍNH XÁC được trả về để mời khách hàng truy xuất bộ sưu tập từ đầu. Điều này là cần thiết bởi vì nó có thể có nghĩa là một số tài nguyên có thể đã được thêm hoặc xóa trước hoặc sau phần hiện được yêu cầu.

Tôi sử dụng ETag / If-Match song song với Last-Modified / If-Unmodified-Because để tối ưu hóa bộ đệm. Các trình duyệt và proxy có thể dựa vào một hoặc cả hai cho các thuật toán bộ đệm của chúng.

Tôi nghĩ rằng một URL nên sạch trừ khi nó bao gồm một truy vấn tìm kiếm / bộ lọc. Nếu bạn nghĩ về nó, một tìm kiếm không có gì khác hơn là một phần của bộ sưu tập. Thay vì những chiếc xe / tìm kiếm? Q = BMW loại URL, chúng ta sẽ thấy nhiều xe hơn? Nhà sản xuất = BMW.


Ý của bạn là "Thực thể yêu cầu không thỏa mãn" hay "413" quá lớn?

1
@Mohamed Tôi nghĩ bạn có nghĩa là If-Unmodified-Since, tương ứng với biến thể E-Tag If-Match, chứ không phải If-Modified-Since. Điều đó nói rằng, bạn cũng có thể xem xét loại bỏ ràng buộc này, tùy thuộc vào trường hợp sử dụng của bạn. Giả sử bạn có một bộ sưu tập chỉ phát triển từ đầu (như một số bộ sưu tập kiểu "mới nhất đầu tiên"), điều tồi tệ nhất có thể xảy ra nếu bộ sưu tập đó thay đổi giữa các yêu cầu là người dùng qua các bộ sưu tập nhìn thấy các mục hai lần. (Bản thân nó cũng là một thông tin hữu ích: Nó cho người dùng biết bộ sưu tập đã thay đổi)
Eugene Beresovsky

20
413 là "Thực thể yêu cầu quá lớn", không phải "Thực thể được yêu cầu quá lớn". Nó có nghĩa là kích thước yêu cầu của bạn, ví dụ như khi tải lên một tệp, lớn hơn máy chủ sẵn sàng xử lý. Vì vậy, sử dụng nó cho điều này dường như không hoàn toàn thích hợp.
user247702

@Mohamed Tôi biết đó là một câu hỏi cũ nhưng nếu ETag của bộ sưu tập là ETag của tài nguyên được sửa đổi gần đây nhất mà bộ sưu tập chứa, thì nên sử dụng giá trị nào của tiêu đề If-Match khi sửa đổi một tài nguyên trong bộ sưu tập? Sử dụng giá trị của ETag được trả về cùng với bộ sưu tập là sai vì khách hàng sẽ có thể sửa đổi tài nguyên ngay cả khi anh ta không nhìn thấy trạng thái cuối cùng của tài nguyên.
Mickael Marrache

8
Tôi hoàn toàn không đồng ý về việc sử dụng 413. Đây là một mã lỗi có nghĩa là máy khách đang gửi một cái gì đó mà máy chủ từ chối chấp nhận do kích thước. Không phải hướng ngược lại! Xem tools.ietf.org/html/rfc7231#section-6.5.11 (lưu ý rằng nó nói tải trọng yêu cầu . Không phải tải trọng phản hồi )!
shoutuma

7

Bạn vẫn có thể trả lại Accept-RangesContent-Rangesvới một 200mã phản hồi. Hai tiêu đề phản hồi này cung cấp cho bạn đủ thông tin để suy ra cùng một thông tin mà 206mã phản hồi cung cấp rõ ràng.

Tôi sẽ sử dụng Rangeđể phân trang, và nó chỉ đơn giản là trả lại 200cho một đồng bằng GET.

Điều này cảm thấy RESTful 100% không làm cho việc duyệt web trở nên khó khăn hơn.

Chỉnh sửa: Tôi đã viết một bài đăng trên blog về điều này: http://otac0n.com/blog/2012/11/21/range-header-i-choose-you.html


5

Nếu có nhiều hơn một trang phản hồi và bạn không muốn cung cấp toàn bộ bộ sưu tập cùng một lúc, điều đó có nghĩa là có nhiều lựa chọn?

Theo yêu cầu /db/questions, hãy trả về 300 Multiple Choicesvới Linkcác tiêu đề chỉ định cách truy cập từng trang cũng như đối tượng JSON hoặc trang HTML có danh sách URL.

Link: <>; rel="http://paged.collection.example/relation/paged"
Link: <>; rel="http://paged.collection.example/relation/paged"
...

Bạn muốn có một Linktiêu đề cho mỗi trang kết quả (một chuỗi rỗng có nghĩa là URL hiện tại, và URL là như nhau cho mỗi trang, chỉ cần truy cập với phạm vi khác nhau), và mối quan hệ được định nghĩa là một tùy chỉnh theo sắp tới Linkđặc tả . Mối quan hệ này sẽ giải thích tùy chỉnh của bạn 266, hoặc vi phạm của bạn 206. Những tiêu đề này là phiên bản có thể đọc được bằng máy của bạn, vì tất cả các ví dụ của bạn đều yêu cầu khách hàng hiểu biết.

(Nếu bạn tuân theo lộ trình "phạm vi", tôi tin rằng 2xxmã trả lại của riêng bạn , như bạn đã mô tả, sẽ là hành vi tốt nhất ở đây. "] và bạn có lý do chính đáng.)

300 Multiple Choicesnói rằng bạn NÊN cũng cung cấp cho cơ thể một cách để tác nhân người dùng chọn. Nếu khách hàng của bạn hiểu, nên sử dụng các Linktiêu đề. Nếu đó là người dùng duyệt thủ công, có lẽ một trang HTML có liên kết đến tài nguyên gốc "phân trang" đặc biệt có thể xử lý kết xuất trang cụ thể đó dựa trên URL? /humanpage/1/db/questionshay cái gì ghê tởm như thế?


Các ý kiến ​​về bài đăng của Richard Levasseur nhắc nhở tôi về một tùy chọn bổ sung: Accepttiêu đề (phần 14.1). Quay lại khi thông số oEmbed xuất hiện, tôi tự hỏi tại sao nó không được thực hiện hoàn toàn bằng cách sử dụng HTTP và đã viết lên một giải pháp thay thế bằng cách sử dụng chúng.

Giữ 300 Multiple Choices, các Linktiêu đề và các trang HTML cho một HTTP ngây thơ ban đầu GET, nhưng thay vì dãy sử dụng, có mối quan hệ phân trang mới của bạn xác định việc sử dụng các Accepttiêu đề. Yêu cầu HTTP tiếp theo của bạn có thể trông như thế này:

GET /db/questions HTTP/1.1
Host: paged.collection.example
Accept: application/json;PagingSpec=1.0;page=1

Các Accepttiêu đề cho phép bạn xác định một loại chấp nhận được nội dung (JSON trở lại của bạn), cộng với thông số mở rộng cho loại đó (số trang của bạn). Đánh dấu các ghi chú của tôi từ bài viết oEmbed của tôi (không thể liên kết với nó ở đây, tôi sẽ liệt kê nó trong hồ sơ của tôi), bạn có thể rất rõ ràng và cung cấp một phiên bản thông số / quan hệ ở đây trong trường hợp bạn cần xác định lại ý nghĩa của pagetham số trong tương lai.


1
Các tiêu đề liên kết +1, nhưng tôi cũng đề xuất các thông tin chung đầu tiên, trước, tiếp theo, cuối cùng, cũng như lưu trữ trước, lưu trữ tiếp theo và hiện tại của RFC5005.
Joseph Holsten

> Theo yêu cầu / db / câu hỏi, trả về 300 Nhiều lựa chọn với các tiêu đề Liên kết chỉ định cách truy cập từng trang [..] Vấn đề với điều đó (và với hầu hết các thiết kế REST thuần túy) là nó sẽ giết chết độ trễ. Mục tiêu là để giảm thiểu các yêu cầu mạng. Yêu cầu đầu tiên đó sẽ mang lại kết quả, không liên kết đến nhiều yêu cầu cuối cùng sẽ cung cấp dữ liệu chúng tôi cần.
Stijn de Witt

4

Biên tập:

Sau khi suy nghĩ thêm một chút, tôi có xu hướng đồng ý rằng các tiêu đề Phạm vi không phù hợp để phân trang. Logic, tiêu đề Range được dành cho phản hồi của máy chủ, không phải cho các ứng dụng. Nếu bạn đã phục vụ 100 megabyte kết quả, nhưng máy chủ (hoặc máy khách) chỉ có thể xử lý 1 megabyte tại một thời điểm, đó là những gì tiêu đề Range dành cho.

Tôi cũng cho rằng một tập hợp con các tài nguyên là tài nguyên của chính nó (tương tự như đại số quan hệ.), Vì vậy nó xứng đáng được đại diện trong URL.

Về cơ bản, tôi đọc lại câu trả lời ban đầu của mình (bên dưới) về việc sử dụng một tiêu đề.


Tôi nghĩ rằng bạn đã trả lời câu hỏi của riêng bạn, ít nhiều - trả lại 200 hoặc 206 với phạm vi nội dung và tùy ý sử dụng tham số truy vấn. Tôi sẽ đánh hơi tác nhân người dùng và loại nội dung và, tùy thuộc vào những người đó, kiểm tra tham số truy vấn. Nếu không, yêu cầu các tiêu đề phạm vi.

Về cơ bản, bạn có các mục tiêu mâu thuẫn - cho phép mọi người sử dụng trình duyệt của họ để khám phá (điều này không dễ dàng cho phép các tiêu đề tùy chỉnh) hoặc buộc mọi người sử dụng một ứng dụng khách đặc biệt có thể đặt các tiêu đề (không cho phép họ khám phá).

Bạn chỉ có thể cung cấp cho họ ứng dụng khách đặc biệt tùy theo yêu cầu - nếu nó trông giống như một trình duyệt đơn giản, hãy gửi xuống một ứng dụng ajax nhỏ hiển thị trang và đặt các tiêu đề cần thiết.

Tất nhiên, cũng có cuộc tranh luận về việc liệu URL có nên chứa tất cả trạng thái cần thiết cho loại điều này hay không. Việc chỉ định phạm vi sử dụng các tiêu đề có thể được coi là "không yên tâm".

Bên cạnh đó, thật tuyệt nếu các máy chủ có thể phản hồi với tiêu đề "Có thể chỉ định: Header1, header2" và trình duyệt web sẽ hiển thị UI để người dùng có thể điền giá trị, nếu họ muốn.


Cảm ơn vì sự trả lời. Tôi đã nghĩ về chủ đề này, nhưng hy vọng có được ý kiến ​​thứ hai. Xảy ra để có một con trỏ cho các đối số tiêu đề?
Karl Guertin

Đây là trang duy nhất tôi đã đánh dấu (xem phần thảo luận trong các bình luận): yetenough.org/blog/2008/05/versioning-rest-web-service Một trang web khác xoay quanh việc sử dụng .json, .xml, .whwh trong việc xác định loại nội dung của một yêu cầu. Một số ví dụ: * ngôn ngữ - đặt nó vào URL có nghĩa là gửi liên kết đến một quốc gia khác sẽ khiến nó sai ngôn ngữ. * phân trang - Đặt nó trong tiêu đề có nghĩa là bạn không thể liên kết mọi người với những gì bạn thấy
Richard Levasseur

* loại nội dung: sự kết hợp của các vấn đề về ngôn ngữ và phân trang - nếu có trong url, nếu khách hàng không hỗ trợ loại nội dung đó (ví dụ: phần mở rộng .ajax và .html) thì sao? Ngược lại, không có loại nội dung đó trong url, bạn không thể đảm bảo cùng một đại diện được đưa ra. "trang web ajax mới! example.com/cool.ajax" vs "bài viết thú vị ở đây: example.com/article.ajax#id=123".
Richard Levasseur

2
IMO, việc nó có đi vào URL hay không phụ thuộc vào nó là gì. Quy tắc chung của tôi là, nếu nó sẽ xác định một tài nguyên cụ thể (có thể là tài nguyên ở trạng thái cụ thể, lựa chọn tài nguyên hoặc kết quả riêng biệt), thì nó sẽ đi vào URL. Truy vấn tìm kiếm, phân trang và giao dịch yên tĩnh là những ví dụ tốt về điều này. Nếu một cái gì đó cần thiết để chuyển đổi biểu diễn trừu tượng thành biểu diễn cụ thể, thì nó sẽ đi vào tiêu đề. thông tin xác thực và loại nội dung là những ví dụ tốt về điều này.
Richard Levasseur

Tôi nghĩ về chuỗi truy vấn trong một URL là các tùy chọn để truy vấn tài nguyên được chỉ định.
wprl

3

Bạn có thể cân nhắc sử dụng một mô hình giống như Giao thức nguồn cấp dữ liệu vì nó có mô hình bộ sưu tập HTTP lành mạnh và cách thao tác với chúng (trong đó điên rồ có nghĩa là WebDAV).

Giao thức xuất bản nguyên tử xác định mô hình bộ sưu tập và các hoạt động REST cộng với bạn có thể sử dụng RFC 5005 - Phân trang và lưu trữ nguồn cấp dữ liệu đến trang thông qua các bộ sưu tập lớn.

Chuyển từ nội dung XML XML sang JSON không nên ảnh hưởng đến ý tưởng.


3

Tôi nghĩ vấn đề thực sự ở đây là không có gì trong thông số kỹ thuật cho chúng ta biết cách thực hiện chuyển hướng tự động khi phải đối mặt với 413 - Thực thể được yêu cầu quá lớn.

Gần đây tôi đã phải vật lộn với vấn đề tương tự này và tôi đã tìm cảm hứng trong cuốn sách Dịch vụ web RESTful . Cá nhân tôi không nghĩ 206 là phù hợp do yêu cầu tiêu đề. Suy nghĩ của tôi cũng đưa tôi đến 300, nhưng tôi nghĩ rằng đó là nhiều hơn cho các loại mime khác nhau, vì vậy tôi đã tìm hiểu những gì mà Richardson và Ruby đã nói về chủ đề này trong Phụ lục B, trang 377. Họ đề nghị rằng máy chủ chỉ chọn ưu tiên đại diện và gửi lại với số 200, về cơ bản bỏ qua khái niệm rằng nó phải là 300.

Điều đó cũng gây tranh cãi với khái niệm liên kết đến các tài nguyên tiếp theo mà chúng ta có từ nguyên tử. Giải pháp tôi đã thực hiện là thêm các khóa "tiếp theo" và "trước đó" vào bản đồ json mà tôi đã gửi lại và được thực hiện với nó.

Sau này tôi bắt đầu nghĩ có lẽ việc cần làm là gửi 307 - Chuyển hướng tạm thời đến một liên kết giống như / db / câu hỏi / 1,25 - để lại URI ban đầu làm tên tài nguyên chính tắc, nhưng nó đưa bạn đến một nguồn tài nguyên cấp dưới được đặt tên thích hợp. Đây là hành vi tôi muốn thấy trong số 413, nhưng 307 có vẻ là một sự thỏa hiệp tốt. Chưa thực sự thử mã này. Điều gì sẽ tốt hơn nữa là chuyển hướng để chuyển hướng đến một URL có chứa ID thực tế của các câu hỏi được hỏi gần đây nhất. Ví dụ: nếu mỗi câu hỏi có ID số nguyên và có 100 câu hỏi trong hệ thống và bạn muốn hiển thị mười câu hỏi gần đây nhất, yêu cầu / db / câu hỏi phải là 307'd đến / db / câu hỏi / 100,91

Đây là một câu hỏi rất hay, cảm ơn vì đã hỏi nó. Bạn đã xác nhận với tôi rằng tôi không phải là người dở hơi vì đã dành nhiều ngày để nghĩ về nó.


303 sẽ tốt hơn về vấn đề này so với 307. 307 ngụ ý rằng URL ban đầu sẽ sớm bắt đầu phản hồi như khách hàng mong đợi.
Nicholas Shanks

RFC 7231 tham chiếu mã trạng thái HTTP 413 là Tải trọng quá lớn và liên quan mã này với kích thước yêu cầu và không phải kích thước phản hồi tiềm năng.
beawolf

1

Bạn có thể phát hiện Rangetiêu đề và bắt chước Dojo nếu nó có mặt và bắt chước Atom nếu không. Dường như với tôi rằng điều này phân chia gọn gàng các trường hợp sử dụng. Nếu bạn đang trả lời một truy vấn REST từ ứng dụng của mình, bạn hy vọng nó sẽ được định dạng bằng một Rangetiêu đề. Nếu bạn đang phản hồi với một trình duyệt thông thường, thì nếu bạn trả về các liên kết phân trang, nó sẽ cho phép công cụ cung cấp một cách dễ dàng để khám phá bộ sưu tập.


1

Một trong những vấn đề lớn với các tiêu đề phạm vi là rất nhiều proxy của công ty lọc chúng ra. Tôi khuyên bạn nên sử dụng một tham số truy vấn thay thế.



0

Dường như với tôi rằng cách tốt nhất để làm điều này là bao gồm phạm vi dưới dạng tham số truy vấn. ví dụ: GET / db / question /? date> mindate & date <maxdate . Khi GET đến / db / câu hỏi / không có tham số truy vấn, hãy trả về 303 với Vị trí: / db / câu hỏi /? Truy vấn-tham số-để-lấy-trang-mặc định-trang . Sau đó, cung cấp một URL khác mà theo đó bất kỳ ai đang sử dụng API của bạn để lấy số liệu thống kê về bộ sưu tập (ví dụ: sử dụng tham số truy vấn nào nếu anh ấy muốn toàn bộ bộ sưu tập);


0

Mặc dù có thể sử dụng tiêu đề Phạm vi cho mục đích này, tôi không nghĩ đó là mục đích. Nó dường như đã được thiết kế để xử lý các kết nối không ổn định cũng như giới hạn dữ liệu (vì vậy khách hàng có thể yêu cầu một phần yêu cầu nếu thiếu thứ gì đó hoặc kích thước quá lớn để xử lý). Bạn đang hack phân trang vào một cái gì đó có khả năng được sử dụng cho các mục đích khác ở lớp giao tiếp. Cách "thích hợp" để xử lý phân trang là với các loại bạn trả về. Thay vì trả về đối tượng câu hỏi, thay vào đó bạn nên trả về một loại mới.

Vì vậy, nếu câu hỏi là như thế này:

<questions> <question index=1></question> <question index=2></question> ... </questions>

Loại mới có thể là một cái gì đó như thế này:

<questionPage> <startIndex>50</startIndex> <returnedCount>10</returnedCount> <totalCount>1203</totalCount> <questions> <question index=50></question> <question index=51></question> .. </questions> <questionPage>

Tất nhiên, bạn kiểm soát các loại phương tiện của mình, vì vậy bạn có thể đặt "trang" của mình thành định dạng phù hợp với nhu cầu của mình. Nếu bạn thực hiện một cái gì đó chung chung, bạn có thể có một trình phân tích cú pháp trên máy khách để xử lý phân trang giống nhau cho tất cả các loại. Tôi nghĩ rằng đó là tinh thần của đặc tả HTTP, hơn là làm mờ tham số Range cho một cái gì đó khác.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.