Я заинтересован в предоставлении прямого интерфейса REST коллекциям документов JSON (представьте себе CouchDB или Persevere ). Проблема, с которой я сталкиваюсь, заключается в том, как обработать операцию GET
в корне коллекции, если коллекция большая.
В качестве примера притворяюсь, что я выставляю таблицу Questions
StackOverflow, где каждая строка представлена в виде документа (не обязательно, что такая таблица обязательно есть, просто конкретный пример значительной коллекции «документов»). Коллекция будет доступна на /db/questions
с обычными CRUD API 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 ( section 14.35 )
указав желаемый диапазон, и МОЖЕТ включить If-Range
поле заголовка ( раздел 14.27 ), чтобы сделать запрос условным.
Это имеет смысл в контексте стандартного использования заголовка, но является проблемой, потому что я хотел бы, чтобы ответом 206 было значение по умолчанию для обработки наивных клиентов / случайных людей, которые исследуют.
Я подробно рассмотрел RFC в поисках решения, но был недоволен моими решениями и заинтересован в том, чтобы SO взялась за эту проблему.
У меня были идеи:
- Возврат
200
с заголовком Content-Range
! - Я не думаю, что это неправильно, но я бы предпочел, чтобы более очевидный показатель того, что ответом является только частичное содержимое.
- Return
400 Range Required
- Специального кода ответа 400 для требуемых заголовков не существует, поэтому ошибка по умолчанию должна использоваться и считываться вручную. Это также усложняет исследование через веб-браузер (или другой клиент, такой как Resty).
- Использовать параметр запроса - Стандартный подход, но я надеюсь разрешить запросы в духе Persevere, и это врезается в пространство имен запроса.
- Просто верните
206
! - я думаю, что большинство клиентов не пугались бы, но я бы не стал идти против MUST в RFC
- Расширьте спецификацию! Return
266 Partial Content
- ведет себя точно так же, как 206, но отвечает на запрос, который НЕ ДОЛЖЕН содержать заголовок Range
. Я считаю, что 266 достаточно высоко, чтобы не сталкиваться с проблемами столкновения, и это имеет для меня смысл, но я не уверен, считается ли это табу или нет.
Я думаю, что это довольно распространенная проблема, и мне бы хотелось, чтобы это было сделано де-факто, чтобы я или кто-то другой не изобретал велосипед.
Какой лучший способ представить полную коллекцию по HTTP, если коллекция большая?