Я заинтересован в предоставлении прямого интерфейса REST коллекциям документов JSON (например, CouchDB или Persevere ). Проблема, с которой я сталкиваюсь, состоит в том, как обработать GET
операцию в корне коллекции, если коллекция большая.
В качестве примера притворяюсь, что я выставляю Questions
таблицу StackOverflow, где каждая строка представлена как документ (не обязательно, что такая таблица обязательно есть, просто конкретный пример значительного набора «документов»). Коллекция будет доступна в /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). - Использовать параметр запроса - стандартный подход, но я надеюсь разрешить запросы а-ля Persevere, и это врезается в пространство имен запроса.
- Просто вернись
206
! - Я думаю, что большинство клиентов не пугались бы, но я бы предпочел не идти против MUST в 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
. Этот заголовок на самом деле кажется идеальным для подкачки.