Как отправить большие объемы данных службе извлечения RESTful без сохранения состояния

Это кажется довольно простым вопросом, поэтому извиняюсь, если об этом задавали раньше; пожалуйста, укажите мне направление любых полезных ресурсов.

Итак, у меня есть служба RESTful для получения некоторых данных. Однако службе RESTful требуется определенный объем данных для выполнения извлечения. Эти данные можно грубо суммировать как данные «контекста пользователя» - информацию о пользователе (независимо от того, хранится ли она вызывающим приложением или ранее получена из другого приложения), которую служба должна использовать для выполнения операции поиска.

Поскольку REST работает семантически, правильным глаголом (методом HTTP) для получения чего-либо является запрос GET. В большинстве примеров GET-запросов, которые я видел, используются только небольшие объемы данных, и данные передаются по URL-адресу. Однако, как только мы перейдем к сфере услуг, которые требуют больших объемов данных для извлечения, кажется неправильным помещать всю эту информацию в URL-адрес. Более того, существуют известные ограничения на длину URL-адресов, которые применяются определенными компонентами (часто 255 символов или около того, IIRC).

По-видимому, доступны следующие варианты:

  • Используйте POST для отправки данных в теле запроса. Однако это не семантически, поскольку мы не просим службу обновлять что-либо, а только получать.
  • Поместите большую часть информации (в моем случае «контекст пользователя») в заголовок HTTP. Однако это «кажется неправильным», поскольку для заголовков следует использовать заголовки, а не данные.
  • Сделайте несколько запросов для отправки данных по нескольким URL-адресам. Однако это, похоже, нарушает цель без сохранения состояния, поскольку служба должна поддерживать какое-то состояние, чтобы связать запросы вместе.
  • Запишите данные в базу данных, а затем передайте службе ключ для извлечения данных оттуда. Однако это приведет к тому, что запрос не будет самодостаточным, а также приведет к возникновению узких мест в производительности.

Есть другой вариант? Какая здесь лучшая практика?


person Adam Burley    schedule 09.01.2015    source источник


Ответы (1)


Заголовки HTTP, такие как путь запроса (URL), не ограничены спецификацией, но имеют ограниченную длину (см. Ссылки ниже).

Вы можете настроить или удалить ограничения сервера, но тогда вам будет намного сложнее поддерживать совместимость со сторонними системами (такими как кеши HTTP), и нет никакой гарантии, что произвольные клиенты HTTP будут поддерживать превышение этих де-факто лимитов тоже.

Единственный способ совместимо отправлять произвольно большие объемы данных на сервер - через тело запроса; из стандартных HTTP-глаголов только запросы POST и PUT могут иметь тела, и из них PUT семантически несовместим с тем, что вы пытаетесь выполнить.

Если вы не можете гарантировать, что вся необходимая информация всегда будет соответствовать URL-адресу или заголовкам запроса (с учетом вышеупомянутых ограничений), вам следует разработать свой REST API, чтобы выразить эту потребность с помощью запроса POST.

Заблуждение, что команда POST используется только для изменения или создания чего-либо на сервере. На самом деле, просто другие глаголы являются идемпотентными (без побочных эффектов, и выполнение повторяющегося запроса должно приводить к дублированию результата), поэтому POST - единственный глагол, который может удовлетворить эти потребности, но в целом POST - это все. для чего-либо другие глаголы не подходят.

POST может законно использоваться в качестве команды извлечения (что чаще приводит к перенаправлению) или обработки, когда ограничения GET не могут быть обойдены иным образом. Ответы POST также можно настроить так, чтобы они больше походили на GET, установив связанные с кешированием заголовки ответов, такие как Cache-Control и Expires.

person krait    schedule 09.01.2015
comment
Хотел бы я проголосовать за это больше одного раза. Я боролся с тем, чтобы слепо использовать HTTP-глаголы только для (моего предположения) их заявленной цели. Я много лет делал то, что считал злоупотреблением глаголом POST, и, наконец, чувствую себя оправданным в своем отношении к POST. Я люблю тебя ПОСЛОМ, никогда не меняй, кто ты есть. - person Mike Devenney; 12.02.2019