Полезная нагрузка HTTP-запроса GET

Я разрабатываю API, и мне интересно, можно ли отправлять полезную нагрузку JSON по запросу GET?

В этом другом вопросе Полезные нагрузки методов HTTP-запросов мы можем найти в соответствии с эту ссылку:

  • HEAD - не определена семантика тела.
  • GET - не определена семантика тела.
  • PUT - поддерживается тело.
  • POST - поддерживается тело.
  • DELETE - не определена семантика тела.
  • TRACE - Тело не поддерживается.
  • ОПЦИИ - Поддерживается тело, но нет семантики (возможно, в будущем).

Означает ли это, что я не должен отправлять запрос GET с полезной нагрузкой? Существуют ли риски для этого?

  • Как у некоторых HTTP-клиентских библиотек, неспособных отправить такую ​​полезную нагрузку?
  • Или мой код Java API не переносится на некоторых серверах приложений?
  • Что-нибудь еще?

Я узнал, что ElasticSearch использовал такую ​​полезную нагрузку в запросе GET:

$ curl -XGET 'http://localhost:9200/twitter/tweet/_search?routing=kimchy' -d '{
    "query": {
        "filtered" : {
            "query" : {
                "query_string" : {
                    "query" : "some query string here"
                }
            },
            "filter" : {
                "term" : { "user" : "kimchy" }
            }
        }
    }
}
'

Итак, если эта популярная библиотека делает это, и никто не жалуется, то, возможно, я могу сделать то же самое?

Кстати, Я хотел бы знать, если это нормально, чтобы смешивать параметры queryString и полезную нагрузку JSON? Точно так же, как это делает запрос ElasticSearch. Если да, существуют ли правила, чтобы мы знали, какие аргументы должны быть параметрами queryString или параметрами полезной нагрузки?


Здесь мы можем прочитать: HTTP GET с телом запроса

Комментарий Роя Филдинг о включении тела с запросом GET.

Да. Другими словами, любому сообщению HTTP-запроса разрешено содержать и, следовательно, должен анализировать сообщения с учетом этого. сервер однако семантика GET ограничена таким, что тело, если оно есть, не имеет семантического значения для запроса. Требования к разбору не зависят от требований по семантике метода.

Итак, да, вы можете отправить тело с GET, и нет, никогда не полезно сделайте это.

Это часть многоуровневой конструкции HTTP/1.1, которая станет понятной снова, когда спецификация разделена (выполняется работа).

.... Рой

Тогда я действительно не понимаю, почему он никогда не бывает полезен, потому что имеет смысл, на мой взгляд, отправлять сложные запросы на сервер, который не подходит для queryParam или matrixParam. Я думаю, что дизайнеры API ElasticSearch думают одинаково...


Я планирую создать API, который можно назвать следующим:

curl -XGET 'http://localhost:9000/documents/inbox?pageIndex=0&pageSize=10&sort=title'

curl -XGET 'http://localhost:9000/documents/trash?pageIndex=0&pageSize=10&sort=title'

curl -XGET 'http://localhost:9000/documents/search?pageIndex=0&pageSize=10&sort=title' -d '{
    "someSearchFilter1":"filterValue1",
    "someSearchFilter2":"filterValue2",
    "someSearchFilterList": ["filterValue3","xxx"]
    ... a lot more ...
}
'

Вам кажется, что это хорошо? Основываясь на приведенных выше соображениях.


Ответ 1

Наличие ответа GET варьируется в зависимости от тела запроса, которое нарушит кеширование. Не ходите туда.

Ответ 2

Google App Engine, популярная веб-инфраструктура, использует специальную библиотеку выборки url, которая не поддерживает запросы HTTP GET с полезной нагрузкой. Соответственно, если вы хотите, чтобы ваш API был доступен пользователям Google App Engine, я бы не рекомендовал это поведение.

Я открыл проблему, связанную с этим, с помощью google.

Ответ 3

Также смотрите: HTTP GET с телом запроса - более подробно об этом.

Суть заключается в следующем: да, но вы, вероятно, не должны по различным причинам, в том числе:

  • Вероятно, вы игнорируете рекомендации спецификации HTTP (вероятно, вы хотите POST).
  • Вы можете ввести проблемы кэширования.
  • Это не интуитивно понятный, поскольку API REST go

Ответ 4

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

Ответы на скоростном плане и Джулиана Решке дают два конкретных примера вещей, которые будут ломаться, если вы будете полагаться на запросы GET с телом/полезной нагрузкой. Вы можете написать свое приложение по-разному всем, если хотите, но сеть - это одна из областей, где стандарты следует воспринимать еще более серьезно, чем обычно. Я знаю, что это заманчиво быть первопроходцем, но при всем уважении, подумайте, сколько сайтов существует, и сколько веб-программистов там строят и поддерживают. Если бы был определенно лучший способ, вы, скорее всего, увидели бы его широко используемым в производстве к настоящему времени.

Изменения стандартов/принимаются медленно, потому что многие люди должны договориться о них, чтобы они работали. Вы правильно говорите, что есть приложения, нарушающие правила, но вы заметите, что они вызвали головные боли для людей, и в некоторых случаях требуются обходные/избыточные меры, о чем упоминается Aetherus в их комментарии к другому ответу. Я склонен идти по пути наименьшего сопротивления по таким вопросам. Если вы действительно хотите это сделать, я уверен, что вы можете заставить его работать.