Подход REST: если данные изменяются, то GET лучше, чем PUT с 1-символьным телом
У нас есть пара приложений REST, которые пытаются получить облегченную версию транзакций, используя URL-адрес подтверждения, который указывает, что обеим сторонам пора "зафиксировать" модификацию. Вот шаги - они не выполняются мгновенно - между шагами могут быть паузы для одобрения конечным пользователем.
- Приложение A одобряет и вносит изменения, уведомляет Приложение B о готовности внести изменения
- Приложение B вносит изменения и уведомляет Приложение A о том, что оно готово, и предоставляет URL подтверждения, что Приложение A "ударит", когда оно выполнит фиксацию.
- Приложение A "нажимает" на URL подтверждения, после получения приложение B фиксирует изменение и возвращает 200. Если приложение A получает 200, они фиксируют изменение, в противном случае каждый откатывается назад.
Вопрос в том, что делать в отношении URL подтверждения. Есть два "разумных" варианта, каждый из которых имеет свои недостатки:
Используйте запрос GET. Недостатком является то, что данные изменяются, и это не должно быть разрешено с помощью GET.
Используйте запрос PUT - это имеет больше смысла, так как данные изменяются и
может случиться только один раз. Но запросы PUT требуют
Заголовок Content-Length и поскольку нет данных для отправки, много HTTP
клиентские библиотеки отказываются устанавливать "Content-Length: 0". Таким образом, они производят "сломанный" PUT, и вы часто (справедливо) получаете 411, когда отправляете PUT без элемента содержимого. Решение состоит в том, чтобы отправить одно символьное тело - оно делает PUT действительным, но выглядит немного отвратительно.
Это узкий вопрос, задающий вопрос о том, следует ли нам разрабатывать протокол с использованием GET или PUT с одним символом.
Просто для ясности, не все клиенты HTTP отказываются отправлять заголовок Content-Length: 0, но Java HttpURLConnection отправит заголовок, только если вы действительно отправляете данные на PUT. И не все HTTP-серверы выдают 411, когда получают PUT без заголовка Content-Length - но Rails (и другие) правильно применяют это правило. Нам нужен этот протокол для работы на всех языках, HTTP-серверах и HTTP-клиентах, поэтому ответ "переписать все в X" не поможет.
Это вопрос философии REST, а не вопрос "какой язык лучше".