Re[33]: Идемпотентность POST - хорошая ли практика?
От: maxkar  
Дата: 04.10.22 11:04
Оценка: 24 (1)
Здравствуйте, gandjustas, Вы писали:

G>Здравствуйте, Sinclair, Вы писали:


S>>В том-то и дело, что в спеке неявно подразумевается, что клиент — единственный, кто взаимодействует с заданным ресурсом на сервере.

G>Я так не думаю. Неглупые люди писали спеку, в первым автором вообще-то филдинг числится.
G>Если в спеке не закладывалась идея "сильной идемпотентности", то есть с сохранением порядка запросов, то, видимо, или другие способы обеспечения есть, или "овчинка не стоит выделки".
Скорее всего, эта идея не рассматривалась. Первые (да и следующие) спецификации HTTP писались преимущественно под браузер и решали соответствующие проблемы. В 1999 году HTTP API были (наравне с ftp и email), но на общем фоне их было мало. 99% HTTP был браузер. Cледы того, что протокол писался под конкретные сценарии, видны даже в эволюции текста. Например, RFC 2616 в части POST говорит про "связные" ресурсы: "new subordinate of the resource identified by the Request-URI". Это хорошо описывает основные сценарии (дополнительные аннотации к существующему ресурсу, создание сообщения на форуме и т.п.). Но тот же RPC over HTTP совершенно не ложится в эту семантику. Поэтому в 2014 году в RFC 7231 POST уже не упоминает никаких субординатов и фокусируется на семантике, специфичной для ресурса: "... according to the resource's own specific semantics".

Соответственно, PUT вводится как хорошая альтернатива для POST с учетом браузерной специфики. Наверное, он задумывался как альтернатива POST для форм:
<form method="PUT" action="/orders/<uniqueServerGeneratedId>">
  ...
</form>

В этом случае браузер в случае обрыва связи не выводил бы предупреждение "обновление страницы может привести к необратимым последствиям" (что он делает в случае POST). А может даже — автоматически повторял бы запрос или предлагал пользователю повторить его. К сожалению, PUT не вошел в список допустимых методов в HTML Cама семантика PUT ("перезаписать" ресурс) соответствует двум основным сценариям. Это создание нового дочернего ресурса (формы). Или просто "создание ресурса" — например, загрузка файла. Т.е. PUT /cats/001.jpg может загружать котика, перезаписывать его. Какие-либо гонки там просто не встречаются. Фокус на браузерах остается и в дальнейших спецификациях. Например, так и не появилось новых глаголов для "повторимых" (идемпотентных) операций, с семантикой, отличной от PUT. А таких операций много. Это и "дельта" (патчи), и определенный класс "RPC-оперций". Например, было бы естественно делать
SomeStronglyIdempotentVerb /orders/123 HTTP/1.1

Content-Type: operations/cancel;f=json;v=1

{"comment": "Don't like the buyer", "manager-id": 123}

Или взять же статусные коды. 404 Not found описывает два совершенно разных класса ошибок. Первый — URL понятен серверу, но ресурс отсутствует. Например, GET /orders/123 — заказ с ID=123 не найден. URL верный, но какие-то параметры не верны. Второй — серверу вообще не понятно, что клиент пытался сказать. Например, GET /wer/ifad/awe?12=nb. С точки зрения браузера проблем здесь нет. Сервер сгенерирует различные странички с описанием. В первом случае — предложит вернуться назад и поискать другой заказ. Во втором — описать шаги для получения ошибки и отправить разработчикам. А вот в случае API отличия более принципиальные. В первом случае вполне вероятна ошибка пользователя (например, оператор неверно ввел номер заказа в форму поиска). А во втором случае это явно ошибка программиста, конфигурировавшего приложение. Да, можно дополнительную информацию передавать в теле сообщения. Но лучше было бы такое важное различие обозначать в кодах.

Нет в HTTP и API-специфичных вещей. Например, я обычно делаю заголовок X-Api-Warning стандартным в ответах (в значениях — коды, которые можно посмотреть в документации по конкретному сервису). Основной сценарий — извещать клиента о том, что его запросы перестают соответствовать требованиям и нужно бы что-то сделать. Например, появился новый API, на который нужно перейти. В этом случае приложение или инфраструктура (service mesh) может обнаружить заголовок и отобразить это в системе мониторинга. Владельцы системы-клиента могут обнаружить это изменение API и со временем мигрировать. Для браузера заголовок смысла не имеет.

В итоге HTTP для API используется не потому, что это идеальный протокол. А потому, что он лучший из существующих. Все остальные (ftp, raw tcp) оказались на практике хуже. В HTTP проблемы (для API) тоже есть, но с ними можно жить. А сам протокол очень широко поддерживается. Есть клиентские библиотеки. Есть вся инфраструктура.
Re[34]: Идемпотентность POST - хорошая ли практика?
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 04.10.22 14:30
Оценка: +1
Здравствуйте, maxkar, Вы писали:

M>Здравствуйте, gandjustas, Вы писали:


G>>Здравствуйте, Sinclair, Вы писали:


S>>>В том-то и дело, что в спеке неявно подразумевается, что клиент — единственный, кто взаимодействует с заданным ресурсом на сервере.

G>>Я так не думаю. Неглупые люди писали спеку, в первым автором вообще-то филдинг числится.
G>>Если в спеке не закладывалась идея "сильной идемпотентности", то есть с сохранением порядка запросов, то, видимо, или другие способы обеспечения есть, или "овчинка не стоит выделки".
M>Скорее всего, эта идея не рассматривалась. Первые (да и следующие) спецификации HTTP писались преимущественно под браузер и решали соответствующие проблемы. В 1999 году HTTP API были (наравне с ftp и email), но на общем фоне их было мало. 99% HTTP был браузер. Cледы того, что протокол писался под конкретные сценарии, видны даже в эволюции текста. Например, RFC 2616 в части POST говорит про "связные" ресурсы: "new subordinate of the resource identified by the Request-URI". Это хорошо описывает основные сценарии (дополнительные аннотации к существующему ресурсу, создание сообщения на форуме и т.п.). Но тот же RPC over HTTP совершенно не ложится в эту семантику. Поэтому в 2014 году в RFC 7231 POST уже не упоминает никаких субординатов и фокусируется на семантике, специфичной для ресурса: "... according to the resource's own specific semantics".

Актуальная спека — 9110 https://www.rfc-editor.org/rfc/rfc9110.html. Дата последней редакции — июнь 2022. Ведущий автор — Рой Филдинг, тот самый который придумал REST.
Вряд ли этот документ можно обвинять в неактуальности, а автора в недальновидности.

M>Фокус на браузерах остается и в дальнейших спецификациях.

Можете дать ссылку на конкретные слова в документе?

M>Например, так и не появилось новых глаголов для "повторимых" (идемпотентных) операций, с семантикой, отличной от PUT. А таких операций много. Это и "дельта" (патчи), и определенный класс "RPC-оперций". Например, было бы естественно делать

Спека говорит что вы можете поддерживать любые глаголы с любой семантикой. Новы обязаны поддерживать идемпотентный PUT.

M>Или взять же статусные коды. 404 Not found описывает два совершенно разных класса ошибок. Первый — URL понятен серверу, но ресурс отсутствует. Например, GET /orders/123 — заказ с ID=123 не найден. URL верный, но какие-то параметры не верны. Второй — серверу вообще не понятно, что клиент пытался сказать. Например, GET /wer/ifad/awe?12=nb

Вы здесь путаете HTTP и REST+HATEOAS. С точки зрения HTTP все ресурсы независимы и равноправны, REST+HATEOAS описывает иерархию и связи.


M>Нет в HTTP и API-специфичных вещей.

И не должно быть. HTTP не ограничивает вас в расширении.

M>В итоге HTTP для API используется не потому, что это идеальный протокол. А потому, что он лучший из существующих.

Идеального вообще ничего не существует.
Re[17]: Идемпотентность POST - хорошая ли практика?
От: Ночной Смотрящий Россия  
Дата: 04.10.22 18:35
Оценка:
Здравствуйте, maxkar, Вы писали:

M>Добавление ключей идемпотентности усложняет схему ...


Вот поэтому я и написал, что такие ключи долджны быть в хидерах, а не в явно прописанных параметрах. И, если это не понятно, они должны быть опциональными. Т.е. если клиент его не передал — значит считаем что это новый ключ.
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[24]: Идемпотентность POST - хорошая ли практика?
От: Ночной Смотрящий Россия  
Дата: 04.10.22 18:35
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Нет, но клиент может полагаться на идемпотентность PUT в силу RFC 2616.


Этот давно уже протух. Актуальный — https://www.rfc-editor.org/rfc/rfc9110
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[28]: Идемпотентность POST - хорошая ли практика?
От: Ночной Смотрящий Россия  
Дата: 04.10.22 18:35
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Вот, к примеру, когда я вижу, что для создания нового экземпляра мне предлагается сделать POST на некий URL, у меня нет никакой информации о том, где я потом буду эту сущность запрашивать.


Рекомендуется в респонсе передавать этот Url в поле location. Посмотри, к примеру, на метод CreatedAtRoute/Action в аспнете.
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[27]: Идемпотентность POST - хорошая ли практика?
От: Ночной Смотрящий Россия  
Дата: 04.10.22 18:54
Оценка: 104 (2)
Здравствуйте, maxkar, Вы писали:

M>Далее. Похоже, в этой теме есть непонимание того, что такое идемпотентность. Прямо по определению (RFC 2616, 9.1.2) идемпотентность говорит, что req(req(state)) == req(state) (и как следствие req(req(req(...(req(state))...))) == req(state). Всё! В общем случае оно даже не гарантирует, что сломавшийся запрос можно безопасно повторять. Причем об этом прямым текстом написано прямо в той же части про идемпотентность.


2616 некоторым образом устарел. А в актуальном 9110 написано так:

A request method is considered "idempotent" if the intended effect on the server of multiple identical requests with that method is the same as the effect for a single such request.

Да и в 2616 еаписано вовсе не про state

the side-effects of N > 0 identical requests is the same as for a single request.

Даже если уж мы говорим про state, то надо понимать что это наблюдаемый c клиента state, а вовсе не реальный state сервера. И да, там таки упоминается что идемпотентность запроса и идемпотентность последовательности запросов это разные вещи.

M>В самом HTTP для существующих глаголов есть два типа идемпотентности.


Это не два типа идемпотентности, это другой признак, называется safety.

M>Если запрос применим в состояниях s1 и s2, то состояние после выполнения запроса одно и то же: req(s1) == req(s2). На практике для безопасного повторения запросов в системах со многими акторами хотелось бы больших гарантий.


В распределенных системах это вряд ли реализуемо, так как упирается в САР-теорему. Максимум можно такое обеспечить для асинхронных операций, и то это будет та еще эквилибристика.
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[34]: Идемпотентность POST - хорошая ли практика?
От: Ночной Смотрящий Россия  
Дата: 04.10.22 19:06
Оценка:
Здравствуйте, maxkar, Вы писали:

M>Нет в HTTP и API-специфичных вещей. Например, я обычно делаю заголовок X-Api-Warning стандартным в ответах (в значениях — коды, которые можно посмотреть в документации по конкретному сервису). Основной сценарий — извещать клиента о том, что его запросы перестают соответствовать требованиям и нужно бы что-то сделать.


И кто будет твой нестандартный хидер читать?
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[33]: Идемпотентность POST - хорошая ли практика?
От: Pauel Беларусь http://blogs.rsdn.org/ikemefula
Дата: 05.10.22 08:46
Оценка:
Здравствуйте, ·, Вы писали:

·>Здравствуйте, Sinclair, Вы писали:


S>>Это всего лишь влияет на то, что B получает в своей выдаче. Относительность времени между A и B означает, что B мог не увидеть X, если сервер трактует его GET как прибывший раньше PUT.

·>Как я понимаю, идемпотентность позоволяет добавить между клиентом и сервером кеширующий прокси.

Кешировать можно только запросы GET, и то не всегда. Кешировать PUT и DELETE это мягко говря преступление, даже если они сто тыщ пяццот раз идемпотентные.
Re[34]: Идемпотентность POST - хорошая ли практика?
От: Ночной Смотрящий Россия  
Дата: 05.10.22 10:51
Оценка:
Здравствуйте, Pauel, Вы писали:

P>Кешировать можно только запросы GET, и то не всегда. Кешировать PUT и DELETE это мягко говря преступление, даже если они сто тыщ пяццот раз идемпотентные.


Ты путаешь кеширование самих запросов и кеширование отклика. Речь идет именно про кеширование самих запросов, правильный термин тут — ретрай. И таки да, есть варианты построения инфраструктуры, когда ретраи происходят не в самом сервисе, а в специальной проксе. Такой вариант позволяет писать сервисы командам широкого спектра квалификаций на широком спектре средств разработки не вынуждая создавать для каждой поддерживаемой платформы полный спектр инструментария. Т.е. это как раз против той самой описанной тобой ситуации с внезапно забытой мидлварей. Ретраи на уровне инфры забыть невозможно в принципе.
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[35]: Идемпотентность POST - хорошая ли практика?
От: Pauel Беларусь http://blogs.rsdn.org/ikemefula
Дата: 05.10.22 13:16
Оценка:
Здравствуйте, Ночной Смотрящий, Вы писали:

P>>Кешировать можно только запросы GET, и то не всегда. Кешировать PUT и DELETE это мягко говря преступление, даже если они сто тыщ пяццот раз идемпотентные.


НС>Ты путаешь кеширование самих запросов и кеширование отклика. Речь идет именно про кеширование самих запросов, правильный термин тут — ретрай.


Кеширование и повторяемые запросы на мой взгляд вещи сильно разные, о чем ты сам говоришь — что правильный термин это ретрай. А я говорю — про кеширование, а не retry.
Re[35]: Идемпотентность POST - хорошая ли практика?
От: Pauel Беларусь http://blogs.rsdn.org/ikemefula
Дата: 06.10.22 09:03
Оценка:
Здравствуйте, Ночной Смотрящий, Вы писали:

M>>Нет в HTTP и API-специфичных вещей. Например, я обычно делаю заголовок X-Api-Warning стандартным в ответах (в значениях — коды, которые можно посмотреть в документации по конкретному сервису). Основной сценарий — извещать клиента о том, что его запросы перестают соответствовать требованиям и нужно бы что-то сделать.


НС>И кто будет твой нестандартный хидер читать?


Консумеры API. Обычно люди, которые используют тот или иной API, делают это не от балды, а осознанно, потому можно ожидать, что они будут пользоваться такими вещами. Если это внутренняя кухня, то это вполне себе работает. Т.е. это просто конвеншн внутри экосистемы, и чем она больше, тем разработчики глубже вникают в таки детали.
Другое дело, если это внешний API, а клиенты были написаны в лучшем случае год назад. Тогда такой подход будет бессмысленным.
Re[36]: Идемпотентность POST - хорошая ли практика?
От: Ночной Смотрящий Россия  
Дата: 06.10.22 09:17
Оценка:
Здравствуйте, Pauel, Вы писали:

НС>>И кто будет твой нестандартный хидер читать?

P>Консумеры API.

И что эти консумеры с ним будут делать?

P> Обычно люди, которые используют тот или иной API, делают это не от балды, а осознанно, потому можно ожидать, что они будут пользоваться такими вещами.


Это все абстрактно. Давай конкретно. Вот есть некий API. К нему кто то написал клиента и использует в своем софте. Вдруг в хидере начинает приходить сообщение о том, что это API устарело. Кто это сообщение увидит?

P>Другое дело, если это внешний API, а клиенты были написаны в лучшем случае год назад. Тогда такой подход будет бессмысленным.


Вот именно.
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[36]: Идемпотентность POST - хорошая ли практика?
От: · Великобритания  
Дата: 06.10.22 09:36
Оценка:
Здравствуйте, Pauel, Вы писали:

НС>>И кто будет твой нестандартный хидер читать?

P>Консумеры API. Обычно люди, которые используют тот или иной API, делают это не от балды, а осознанно, потому можно ожидать, что они будут пользоваться такими вещами. Если это внутренняя кухня, то это вполне себе работает. Т.е. это просто конвеншн внутри экосистемы, и чем она больше, тем разработчики глубже вникают в таки детали.
Сделай емейл-рассылку или сайт для новостей, телеграмм-канал какой-нибудь. Трафик съэкономишь.

P>Другое дело, если это внешний API, а клиенты были написаны в лучшем случае год назад. Тогда такой подход будет бессмысленным.

Угу.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[37]: Идемпотентность POST - хорошая ли практика?
От: Pauel Беларусь http://blogs.rsdn.org/ikemefula
Дата: 06.10.22 10:06
Оценка:
Здравствуйте, Ночной Смотрящий, Вы писали:

НС>>>И кто будет твой нестандартный хидер читать?

P>>Консумеры API.

НС>И что эти консумеры с ним будут делать?


Будут поступать в соответствии с соглашением.

P>> Обычно люди, которые используют тот или иной API, делают это не от балды, а осознанно, потому можно ожидать, что они будут пользоваться такими вещами.


НС>Это все абстрактно. Давай конкретно. Вот есть некий API. К нему кто то написал клиента и использует в своем софте. Вдруг в хидере начинает приходить сообщение о том, что это API устарело. Кто это сообщение увидит?


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

ты почему то видишь только п2 но не видишь п1
Re[37]: Идемпотентность POST - хорошая ли практика?
От: Pauel Беларусь http://blogs.rsdn.org/ikemefula
Дата: 06.10.22 10:08
Оценка:
Здравствуйте, ·, Вы писали:

P>>Консумеры API. Обычно люди, которые используют тот или иной API, делают это не от балды, а осознанно, потому можно ожидать, что они будут пользоваться такими вещами. Если это внутренняя кухня, то это вполне себе работает. Т.е. это просто конвеншн внутри экосистемы, и чем она больше, тем разработчики глубже вникают в таки детали.

·>Сделай емейл-рассылку или сайт для новостей, телеграмм-канал какой-нибудь. Трафик съэкономишь.

Зачем? У нас внутри экосистемы подобные механизмы документированы и поддерживаются всеми клиентам. Консумер или берет такой клиент, или пилит свой с учетом конвеншна.

P>>Другое дело, если это внешний API, а клиенты были написаны в лучшем случае год назад. Тогда такой подход будет бессмысленным.

·>Угу.

Что уго? Типа внешний апи это единственный кейс?
Re[38]: Идемпотентность POST - хорошая ли практика?
От: Ночной Смотрящий Россия  
Дата: 06.10.22 10:28
Оценка:
Здравствуйте, Pauel, Вы писали:

НС>>И что эти консумеры с ним будут делать?

P>Будут поступать в соответствии с соглашением.

К чему эти отписки? Напиши честно — не знаю.

НС>>Это все абстрактно. Давай конкретно. Вот есть некий API. К нему кто то написал клиента и использует в своем софте. Вдруг в хидере начинает приходить сообщение о том, что это API устарело. Кто это сообщение увидит?

P>Я дал тебе ответ.

Нет.

P>1. для экосистемы построеной вокруг конвеншна, все это уже поддерживается


Каким образом? Я же написал — давай конкретно, а от тебя опять абстрактные рассуждения.
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[39]: Идемпотентность POST - хорошая ли практика?
От: Pauel Беларусь http://blogs.rsdn.org/ikemefula
Дата: 06.10.22 10:41
Оценка:
Здравствуйте, Ночной Смотрящий, Вы писали:

НС>>>И что эти консумеры с ним будут делать?

P>>Будут поступать в соответствии с соглашением.

НС>К чему эти отписки? Напиши честно — не знаю.


Я пишу о том, как это уже работает внутри экосистемы. И с этим работают не только аритекторы и разработчики приложений, но и ops, l2, qa и тд.

P>>1. для экосистемы построеной вокруг конвеншна, все это уже поддерживается


НС>Каким образом? Я же написал — давай конкретно, а от тебя опять абстрактные рассуждения.


Что именно ты ждешь? Код, контакт, или запись видео? Внятно вопрос сформулируй.
Re[38]: Идемпотентность POST - хорошая ли практика?
От: · Великобритания  
Дата: 06.10.22 10:42
Оценка:
Здравствуйте, Pauel, Вы писали:

P>>>Консумеры API. Обычно люди, которые используют тот или иной API, делают это не от балды, а осознанно, потому можно ожидать, что они будут пользоваться такими вещами. Если это внутренняя кухня, то это вполне себе работает. Т.е. это просто конвеншн внутри экосистемы, и чем она больше, тем разработчики глубже вникают в таки детали.

P>·>Сделай емейл-рассылку или сайт для новостей, телеграмм-канал какой-нибудь. Трафик съэкономишь.
P>Зачем?
Меньше трафика. Послать емейл — один раз, а хедер будет в каждом ответе. Да и у емейла больше шанса, что его прочитают и отреагируют.

P>У нас внутри экосистемы подобные механизмы документированы и поддерживаются всеми клиентам. Консумер или берет такой клиент, или пилит свой с учетом конвеншна.

Ты так и не обосновал, зачем это пихать в каждый ответ. Чем это принципиально отличается от простой публикации changelog консьюмерам.

Я ещё понимаю, если посылать номер версии в хедере "Server" или каком-нибудь "X-My-API-Version". Так консумеры могут догадаться, что с v1.2.3 работало, а с v1.2.4 что-то вдруг подглючивать стало, значит стоит поподробнее changelog почитать. Но что делать с Warning?

P>>>Другое дело, если это внешний API, а клиенты были написаны в лучшем случае год назад. Тогда такой подход будет бессмысленным.

P>·>Угу.
P>Что уго? Типа внешний апи это единственный кейс?
Да в любом кейсе это бессмысленно.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[40]: Идемпотентность POST - хорошая ли практика?
От: Ночной Смотрящий Россия  
Дата: 06.10.22 10:46
Оценка:
Здравствуйте, Pauel, Вы писали:

НС>>К чему эти отписки? Напиши честно — не знаю.

P>Я пишу о том, как это уже работает внутри экосистемы. И с этим работают не только аритекторы и разработчики приложений, но и ops, l2, qa и тд.

Каким образом они работают? Я не понимаю кто и в какой момент увидит этот хидер.

P>>>1. для экосистемы построеной вокруг конвеншна, все это уже поддерживается

НС>>Каким образом? Я же написал — давай конкретно, а от тебя опять абстрактные рассуждения.
P>Что именно ты ждешь? Код, контакт, или запись видео? Внятно вопрос сформулируй.

Я жду ответа на простой вопрос: "кто будет твой нестандартный хидер читать"?
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[39]: Идемпотентность POST - хорошая ли практика?
От: Ночной Смотрящий Россия  
Дата: 06.10.22 10:48
Оценка:
Здравствуйте, ·, Вы писали:

·>Я ещё понимаю, если посылать номер версии в хедере "Server" или каком-нибудь "X-My-API-Version".


Это тоже бессмысленно, потому что в нормальном REST url будет вида /api/vXX/collection. И в рамках конкретного vXX никаких ломающих изменений и устаревших API в принципе быть не может.
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.