Глагол поиска в HTTP API

Что лучше всего подходит для поиска в API?

  • GET + параметры запроса, пример: GET /search?q=phone
  • GET + параметры в теле, пример: GET /search {"query": "phone"}
  • POST + параметры в теле, пример: POST /search {"query": "phone"}

person Romper    schedule 11.05.2017    source источник


Ответы (3)


Не включайте тело в запрос GET. Это противоречит спецификации:

Полезная нагрузка в сообщении запроса GET не имеет определенной семантики; отправка тела полезной нагрузки в запросе GET может привести к тому, что некоторые существующие реализации отклонят запрос.

Между двумя другими вариантами есть компромиссы. Запросы GET кэшируются, безопасны и идемпотентны. Они также ограничены по размеру.

Запросы POST не являются надежно кэшируемыми, безопасными или идемпотентными, а также не имеют ограничений по размеру. Также заложена большая гибкость — вы можете позже создать ресурс фильтра на стороне сервера в дополнение к возврату результата поиска, и более поздние поиски могут использовать этот фильтр, возможно, с помощью GET, хотя будьте осторожны, если вы разрешаете кэширование и изменения в определение фильтра после его создания.

Глядя на ваш конкретный пример, поддержка одной конечной точки «поиск» может довольно быстро запутаться. Если вы еще этого не сделали, я бы посоветовал вам рассмотреть другие варианты.

person Eric Stein    schedule 11.05.2017
comment
Elasticsearch использует GET с телом для поисковых запросов. - person Romper; 11.05.2017
comment
@Romper Конечно, да. Они отказались от идемпотентности и кешируемости, потому что считают, что GET должен означать получить что-то, а POST — что-то изменить. Я не согласен с их решением, и они явно нарушают спецификацию, как написано и как задумано. Авторы спецификации ясно дали понять, что они хотели, чтобы тела GET были семантически бессмысленными. - person Eric Stein; 11.05.2017
comment
@Romper Да, с явной информацией о свежести ответ может быть кэширован. Однако некоторые пользовательские агенты и промежуточные серверы этого не делают, даже если это разрешено спецификацией. Ответы на запросы POST кэшируются только в том случае, если они включают явную информацию о свежести (см. раздел 4.2.1 [RFC7234]). Однако кэширование POST широко не применяется. [RFC7231 4.3.3]. Таким образом, даже если вы хотите кэшировать, вы зависите от чего-то от клиента до границы вашей службы, поддерживающей кэширование POST. - person Eric Stein; 11.05.2017

Считается, что запросы POST изменяют или создают данные на сервере. GET считается «безопасным методом», который не влияет на базу данных сервера.

Поскольку поисковые запросы обычно не изменяют никаких данных, вам следует использовать запрос GET. Ограничение составляет не менее 2000 символов (IE), поэтому в большинстве случаев вы в безопасности.

person Tobias    schedule 11.05.2017
comment
Поскольку семантика полезной нагрузки POST зависит от разработчика, запросы POST представляют собой армейский нож HTTP-операций, которые следует использовать, если ни одна из других, более конкретных операций не подходит. POST - это не только операция создания ресурса... - person Roman Vottner; 11.05.2017

Обязательно сделайте 1, GET, используя параметры запроса. Вероятность кэширования гораздо выше.

Если на сервере ничего не меняется в модели данных, ваш запрос должен быть GET. Серверные операции, такие как ведение журнала, в порядке, но создание фильтра (как предлагалось в другом ответе), в отличие от кеша запросов, скажем, нет.

person Nicholas Shanks    schedule 11.05.2017