Я заинтересован в предоставлении прямого интерфейса 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. Этот заголовок на самом деле кажется идеальным для подкачки.