Мені цікаво розкривати прямий інтерфейс REST до колекцій документів JSON (думаю, CouchDB або Persevere ). Проблема, з якою я стикаюся, полягає в тому, як керувати GET
операцією над коренем колекції, якщо колекція велика.
Як приклад робимо вигляд, що я розкриваю таблицю StackOverflow, Questions
де кожен рядок виставляється як документ (не те, що обов'язково є така таблиця, лише конкретний приклад значної колекції "документів"). Колекція буде доступна в /db/questions
зі звичайним CRUD апі GET /db/questions/XXX
, PUT /db/questions/XXX
, POST /db/questions
знаходиться в грі. Стандартний спосіб отримати всю колекцію - це, GET /db/questions
але якщо це наївно скидає кожен рядок як об'єкт JSON, ви отримаєте досить значне завантаження та багато роботи з боку сервера.
Рішення - це, звичайно, пейджінг. Dojo вирішив цю проблему у своєму JsonRestStore за допомогою розумного розширення, сумісного з RFC2616, із застосуванням Range
заголовка із користувацьким блоком діапазону items
. У результаті виходить 206 Partial Content
лише запитуваний діапазон. Перевага цього підходу над параметром запиту полягає в тому, що він залишає рядок запиту для ... запитів (наприклад, GET /db/questions/?score>200
або дещо, і так, що було б закодовано %3E
).
Цей підхід повністю охоплює поведінку, яку я хочу. Проблема полягає в тому, що RFC 2616 вказує, що на реакцію 206 (міна акценту):
Запит повинен бути включений в поле заголовка Range ( розділ 14.35 ) , яке вказує бажаний діапазон, і може включити поле заголовка If-Range ( розділ 14.27 ) , щоб зробити запит умовним.
Це має сенс у контексті стандартного використання заголовка, але це проблема, тому що я хотів би, щоб реакція 206 була за замовчуванням для обробки наївних клієнтів / випадкових людей, які досліджують.
Я детально переглянув RFC, шукаючи рішення, але був незадоволений своїми рішеннями і зацікавлений у прийнятті проблеми SO.
У мене були ідеї:
- Повернення
200
ізContent-Range
заголовком! - Я не вважаю, що це неправильно, але я вважаю за краще, якщо більш очевидний показник того, що відповідь є лише частковим вмістом. - Повернення
400 Range Required
- не існує спеціального коду відповіді 400 для необхідних заголовків, тому помилка за замовчуванням повинна використовуватися і читатися вручну. Це також ускладнює пошук через веб-браузер (або якийсь інший клієнт, наприклад Resty). - Використовувати параметр запиту - Стандартний підхід, але я сподіваюся дозволити запити a la Persevere і це скоротить область простору імен запитів.
- Просто повертайся
206
! - Я думаю, що більшість клієнтів не злякаються, але я б краще не йшов проти ОБОВ'ЯЗКУ в RFC - Розширити специфікацію! Повернення
266 Partial Content
- поводиться точно так само, як 206, але відповідає на запит, який НЕ повинен міститиRange
заголовка Я вважаю, що 266 є досить високим, що я не повинен стикатися з проблемами зіткнення, і для мене це має сенс, але мені не зрозуміло, вважається це табу чи ні.
Я думаю, що це досить поширена проблема, і я хотів би, щоб це було зроблено якось де-факто, щоб я чи хтось ще не винаходив колесо.
Який найкращий спосіб відкрити повну колекцію через HTTP, коли колекція велика?
Range = "Range" ":" ranges-specifier
де останній у tools.ietf.org/html/rfc2616#section-14.35.1 описується лише як "специфікатор діапазонів байтів", який повинен починатися з "одиниці байтів", що визначається як рядок "байтів" ".
Content-Range
Тема відноситься до тіла (можна використовувати із запитом при завантаженні великих файлів і т.д., або для відповіді при завантаженні). Range
Заголовка використовується для запиту певного діапазону. Слід відповісти, 206
коли Range
заголовок був включений у запит. Якщо цього не було, відповідь все ще може містити Content-Range
заголовок, але код відповіді повинен бути 200
. Цей заголовок насправді здається ідеальним для підкачки.