Я заинтересован в предоставлении прямого интерфейса REST для коллекций документов JSON (например, CouchDB или Настойчиво). Проблема, с которой я сталкиваюсь, заключается в том, как обрабатывать операцию GET в корне коллекции, если коллекция большая.
В качестве примера представьте, что я выставляю таблицу StackOverflow Questions, где каждая строка представлена как документ (не обязательно такая таблица, просто конкретный пример значительной коллекции «документов»). Коллекция будет доступна на /db/questions с использованием обычного API 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! — я думаю, что большинство клиентов не будут волноваться, но я бы не стал нарушать ДОЛЖЕН в RFC - Расширьте спецификацию! Возврат
266 Partial Content— ведет себя точно так же, как 206, но является ответом на запрос, который НЕ ДОЛЖЕН содержать заголовокRange. Я полагаю, что 266 достаточно высок, чтобы не столкнуться с проблемами коллизий, и для меня это имеет смысл, но я не понимаю, считается ли это табу или нет.
Я думаю, что это довольно распространенная проблема, и я хотел бы, чтобы это делалось де-факто, чтобы я или кто-то еще не изобретал велосипед.
Каков наилучший способ предоставить полную коллекцию через HTTP, когда коллекция большая?
Range = "Range" ":" ranges-specifier, где последний в tools.ietf.org/html/rfc2616# section-14.35.1 описывается просто как спецификатор диапазонов байтов, который должен начинаться с блока байтов, который определяется как строка байтов. - person Brett Zamir   schedule 21.06.2013Content-Rangeприменяется к телу (может использоваться с запросом при загрузке больших файлов и т. д. или для ответа при загрузке). ЗаголовокRangeиспользуется для запроса определенного диапазона. Следует ответить206, когда заголовокRangeбыл включен в запрос. Если это не так, ответ может по-прежнему включать заголовокContent-Range, но код ответа должен быть200. Этот заголовок на самом деле кажется идеальным для пейджинга. - person Stijn de Witt   schedule 10.05.2017