Re[3]: Идемпотентность POST - хорошая ли практика?
От: Ночной Смотрящий Россия  
Дата: 20.09.22 09:25
Оценка: 1 (1)
Здравствуйте, Pauel, Вы писали:

НС>>Еще один не самый лучший момент — явное вытаскивание этого idempotency_key в бизнес-слой. Разумнее было бы передавать в каком нибудь хидере типа X-Request-ID, так как это не бизнес-сущность, а специфика транспорта.


P>А что это принципиально меняет?


Логичность и понятность API.

P> Все равно нам нужно по этому x-request-id понять, что делать с повторным запросом. И это уже не транспорт, а бизнес-логика.


Неа. Бизнес-логика, это если ключ присутствует на бизнес-уровне. А вот если ключ специальный и ей ортогонален, то не нужно тащить его в бизнес-слой.
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[2]: Идемпотентность POST - хорошая ли практика?
От: Shmj Ниоткуда  
Дата: 20.09.22 09:26
Оценка:
Здравствуйте, Ночной Смотрящий, Вы писали:

S>>И если уж так подойти — то запросы POST вообще лишены смысла — ведь они не идемпотентны, а это плохо всегда, т.к. если можно сделать идемпотентным

НС>А если нельзя?

На пример в каком случае?
=сначала спроси у GPT=
Re[5]: Идемпотентность POST - хорошая ли практика?
От: samius Япония http://sams-tricks.blogspot.com
Дата: 20.09.22 09:27
Оценка:
Здравствуйте, Shmj, Вы писали:

S>Аналогично PUT — он полностью заменяет запись и будет всегда возвращать одно и тоже, не зависимо от очередности вызовов.

Это не так, см. спецификацию. Может вернуть 201, 200/204.
Re[3]: Идемпотентность POST - хорошая ли практика?
От: karbofos42 Россия  
Дата: 20.09.22 09:29
Оценка:
Здравствуйте, Shmj, Вы писали:

S>Выше вам хорошо ответили. Без ключа идемпотентности — да, запись была бы заблокирована. С ключом идемпотентности, а он один и тот же для всех 4 запросов — первый раз отработали, на все остальные сказали что все ОК.


т.е. хоть и не POST, но нужно что-то отдельно мудрить для идемпотентности?
В итоге только POST не идемпотентный или таки название метода ничего не значит?
Re[9]: Идемпотентность POST - хорошая ли практика?
От: karbofos42 Россия  
Дата: 20.09.22 09:32
Оценка: -1
Здравствуйте, Shmj, Вы писали:

S>Это уже другой вопрос — вопрос безопасности. Даже если ты установишь лимит — 1 клиент 1 заказ — это не спасет от подобной ситуации, т.к. мамкин кулхацкер с легкостью создаст несколько учеток даже с разных IP-адресов и точно так вызовет 1000 машин, можно даже на разные адреса.


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

НС>>А если нельзя?

S>На пример в каком случае?

Например, если ты делаешь health check.
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[5]: Идемпотентность POST - хорошая ли практика?
От: karbofos42 Россия  
Дата: 20.09.22 09:41
Оценка:
Здравствуйте, Shmj, Вы писали:

S>DELETE должен вернуть 200, даже если запись была удалена ранеее. Именно по этому считаем идемпотентным.


Кому он должен?
Вообще-то мне может требоваться, чтобы DELETE именно сообщал была ли запись удалена мною или её изначально не было.

S>Аналогично PUT — он полностью заменяет запись и будет всегда возвращать одно и тоже, не зависимо от очередности вызовов.


А если на сервере кто-то подписан на изменения записей и запускает какую-то операцию?
Ну, может изменения в профиле организации в итоге должен живой модератор проверить и сравнить их со сканами документов.
Заставим человека одни и те же данные дважды проверять и плевать, лишь бы на клиент одинаково код 200 улетел?

S>Вот табличка, уже приводил:


Ага. Табличка по которой все методы отличные, только чтобы у пользователя учётка не заблокировалась из-за плохого интернета, в замечательные индеподентный запрос нужно так же отдельно мудрить ключи.
Re[4]: Идемпотентность POST - хорошая ли практика?
От: Shmj Ниоткуда  
Дата: 20.09.22 09:43
Оценка:
Здравствуйте, karbofos42, Вы писали:

K>т.е. хоть и не POST, но нужно что-то отдельно мудрить для идемпотентности?

K>В итоге только POST не идемпотентный или таки название метода ничего не значит?

См. табличку:

  Скрытый текст


PATCH — не идемпотентен. Т.е. ключ добавлять обязательно, если она нужна.

А PUT — не подходит для обновления пароля — он обновляет целиком всю запись и должен обеспечивать идемпотентность. Это возможно только для сущностей без состояния.
=сначала спроси у GPT=
Re[4]: Идемпотентность POST - хорошая ли практика?
От: Pauel Беларусь http://blogs.rsdn.org/ikemefula
Дата: 20.09.22 09:45
Оценка: +1
Здравствуйте, Ночной Смотрящий, Вы писали:

НС>Логичность и понятность API.


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

@Post('/orders')
newOrder(order: Delta<Order>, idempotencyKey: string): Promise<Order>


В данном случае мы явно явно требуем идемпотентность, и это будет работать вне зависимости от транспорта.

@Post('/orders')
@Idempotent()
newOrder(order: Delta<Order>): Promise<Order>


Соответсвенно на стороне бакенда всё это отражается 1 в 1, только второй вариант хуже с т.з. разработки, т.к. важный степ уходит неизвестно куда.

P>> Все равно нам нужно по этому x-request-id понять, что делать с повторным запросом. И это уже не транспорт, а бизнес-логика.


НС>Неа. Бизнес-логика, это если ключ присутствует на бизнес-уровне. А вот если ключ специальный и ей ортогонален, то не нужно тащить его в бизнес-слой.


А где и как ты собираешься проверять, повторный ли это реквест и в каком он состоянии?

Идемпотентность это свойство прежде всего бизнес-операции. Соответсвенно реализация этого свойства требует в т.ч. и поддержки транспортом. Но первично именно свойство бизнес-операции.
Re[6]: Идемпотентность POST - хорошая ли практика?
От: Shmj Ниоткуда  
Дата: 20.09.22 09:49
Оценка: :)
Здравствуйте, karbofos42, Вы писали:

K>Кому он должен?

K>Вообще-то мне может требоваться, чтобы DELETE именно сообщал была ли запись удалена мною или её изначально не было.

См. табличку:

  Скрытый текст


Таковы правила. Вам либо принять либо город городить.

S>>Аналогично PUT — он полностью заменяет запись и будет всегда возвращать одно и тоже, не зависимо от очередности вызовов.


K>А если на сервере кто-то подписан на изменения записей и запускает какую-то операцию?

K>Ну, может изменения в профиле организации в итоге должен живой модератор проверить и сравнить их со сканами документов.
K>Заставим человека одни и те же данные дважды проверять и плевать, лишь бы на клиент одинаково код 200 улетел?

Тогда нельзя использовать PUT — только PATCH.

K>Ага. Табличка по которой все методы отличные, только чтобы у пользователя учётка не заблокировалась из-за плохого интернета, в замечательные индеподентный запрос нужно так же отдельно мудрить ключи.


Разберитесь.
=сначала спроси у GPT=
Re[5]: Идемпотентность POST - хорошая ли практика?
От: vsb Казахстан  
Дата: 20.09.22 10:19
Оценка: +1
Здравствуйте, Shmj, Вы писали:

S>DELETE должен вернуть 200, даже если запись была удалена ранеее. Именно по этому считаем идемпотентным.


А разве идемпотентность требует возвращать один и тот же код ответа? Мне это не очевидно.

Почему бы первому DELETE не возвращать 200, а последующим 404? Вроде это ничему не противоречит. А то, что код возврата разный, ну и что.

Да и как вообще реализовать DELETE, который будет возвращать 200 на удалённый ресурс? Это из базы нельзя ничего удалять?

В общем тут важно не переходить грань, где транспорт начнёт диктовать бизнес-логике что-то, я считаю.
Re[6]: Идемпотентность POST - хорошая ли практика?
От: Shmj Ниоткуда  
Дата: 20.09.22 10:44
Оценка:
Здравствуйте, vsb, Вы писали:

S>>DELETE должен вернуть 200, даже если запись была удалена ранеее. Именно по этому считаем идемпотентным.


vsb>А разве идемпотентность требует возвращать один и тот же код ответа? Мне это не очевидно.

vsb>Почему бы первому DELETE не возвращать 200, а последующим 404? Вроде это ничему не противоречит. А то, что код возврата разный, ну и что.

Сорри, все-таки верно — второй DELETE вернет ошибку, однако же не поменяет состояние объекта.

Clearly, the response is different from the first request, but there is no change of state for any resource on the server-side because the original resource is already deleted.


тут
=сначала спроси у GPT=
Re[3]: Идемпотентность POST - хорошая ли практика?
От: fmiracle  
Дата: 20.09.22 10:48
Оценка: 79 (2) +3
Здравствуйте, Pauel, Вы писали:

НС>>Еще один не самый лучший момент — явное вытаскивание этого idempotency_key в бизнес-слой. Разумнее было бы передавать в каком нибудь хидере типа X-Request-ID, так как это не бизнес-сущность, а специфика транспорта.

P>А что это принципиально меняет? Все равно нам нужно по этому x-request-id понять, что делать с повторным запросом. И это уже не транспорт, а бизнес-логика.

Можно сделать общее правило, что если передан такой ключ, то прежде чем отдавать данные на обработку в бизнес-логику проверить наличие уже отправленного ранее ответа на этот ключ и отослать его, если он был (для REST с учетом глагола можно сделать чуть разную логику для post/put/delete если есть желание).
Это можно сделать каким-то промежуточным слоем, который будет отрабатывать для всех запросов вообще и одинаково. Но значение ключа при этом тогда гораздо удобнее держать не частью бизнес-данных запроса, а чем-то техническим — хидер для rest, или поле в конверте, например, если у нас какой-то свой протокол.

При появлении нового запроса в АПИ достаточно будет прописать тот же хидер и вся магия для него заработает сразу, без каких-то правок. А если уж вдруг для каких-то запросов "стандартный" механизм не подходит, то убрать этот общий хидер и делать отдельно на урвоне бизнес-логики.
Re[2]: Идемпотентность POST - хорошая ли практика?
От: fmiracle  
Дата: 20.09.22 10:50
Оценка: +1
Здравствуйте, Ночной Смотрящий, Вы писали:

НС>Еще один не самый лучший момент — явное вытаскивание этого idempotency_key в бизнес-слой. Разумнее было бы передавать в каком нибудь хидере типа X-Request-ID, так как это не бизнес-сущность, а специфика транспорта.


Это в статье пример для простоты понимания. Там же в тексте указаны реальные примеры приложений с таким подходом и как раз написано, что для них используются заголовки.
Re[5]: Идемпотентность POST - хорошая ли практика?
От: Ночной Смотрящий Россия  
Дата: 20.09.22 11:04
Оценка: 5 (1)
Здравствуйте, Pauel, Вы писали:

P>На самом деле если абстрагироваться от хттп


Абстрагироваться от хттп это прямо совсем не про REST, а здесь таки REST обсуждается.

НС>>Неа. Бизнес-логика, это если ключ присутствует на бизнес-уровне. А вот если ключ специальный и ей ортогонален, то не нужно тащить его в бизнес-слой.

P>А где и как ты собираешься проверять, повторный ли это реквест и в каком он состоянии?

В мидлвере.

P>Идемпотентность это свойство прежде всего бизнес-операции.


Однако обеспечение этой идемпотентности при помощи отдельного ключа — штука весьма универсальная, и не нужно ее копипастить в бизнес-коде по всем идемпотентным методам.
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[6]: Идемпотентность POST - хорошая ли практика?
От: Ночной Смотрящий Россия  
Дата: 20.09.22 12:48
Оценка: 5 (1) +1
Здравствуйте, karbofos42, Вы писали:

K>Вообще-то мне может требоваться, чтобы DELETE именно сообщал была ли запись удалена мною или её изначально не было.


В общем случае это невозможно. У тебя может запрос на удаление успешно дойти, а вот отклик сервера потеряться. При таком раскладе, если DELETE будет возвращать при удалении уже удаленного 404, ты никогда не получишь на клиенте для этого ресурса 200.
Поэтому строить клиентскую логику на основании того, что вернул DELETE — отличный способ подложить себе грабли.
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[5]: Идемпотентность POST - хорошая ли практика?
От: Ночной Смотрящий Россия  
Дата: 20.09.22 12:51
Оценка:
Здравствуйте, Shmj, Вы писали:

S>А PUT — не подходит для обновления пароля — он обновляет целиком всю запись


Так сделай пароль отдельным ресурсом и обновляй его целиком.
В более хитрых ситуациях может понадобится хранить несколько паролей, да еще и со связанной с ними информацией типа даты создания. Это уже точно отдельный ресурс.
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[6]: Идемпотентность POST - хорошая ли практика?
От: Shmj Ниоткуда  
Дата: 20.09.22 13:08
Оценка:
Здравствуйте, Ночной Смотрящий, Вы писали:

НС>Здравствуйте, Shmj, Вы писали:


S>>А PUT — не подходит для обновления пароля — он обновляет целиком всю запись


НС>Так сделай пароль отдельным ресурсом и обновляй его целиком.

НС>В более хитрых ситуациях может понадобится хранить несколько паролей, да еще и со связанной с ними информацией типа даты создания. Это уже точно отдельный ресурс.

Там же нужно передать и старый пароль.

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

По этому только PATCH.
=сначала спроси у GPT=
Re[7]: Идемпотентность POST - хорошая ли практика?
От: karbofos42 Россия  
Дата: 20.09.22 14:12
Оценка:
Здравствуйте, Ночной Смотрящий, Вы писали:

НС>В общем случае это невозможно. У тебя может запрос на удаление успешно дойти, а вот отклик сервера потеряться. При таком раскладе, если DELETE будет возвращать при удалении уже удаленного 404, ты никогда не получишь на клиенте для этого ресурса 200.

НС>Поэтому строить клиентскую логику на основании того, что вернул DELETE — отличный способ подложить себе грабли.

Так если я не получу ответ от сервера, то клиент повторно ему запрос на удаление отправит, когда связь восстановится (либо вообще это в рамках TCP разрулится и разработчика не волнует).
Дальше и появляется вопрос:
либо сервер увидит, что это повтор уже обработанного запроса и ответит то же самое, что отвечал уже и оно потерялось
либо серверу плевать, он обработает ещё раз удаление и уже не 200, а 404 отправит.
Кроме удаления по ИД, может быть и удаление по какому-нибудь условию.
И будет странно, если "потерянный" запрос сначала удалит 10 записей в БД, а потом я пользователю покажу, якобы не удалилось ничего.
Сначала пользователь удивится почему это ничего не удалилось, ведь он правильно всё выбрал.
Потом он удивится, когда увидит, что данных действительно больше нет.
И в третий раз удивится, когда начнёт искать в журнале/логе кто там его данные удалил и увидит, что это он.
А разработчики потом будут искать отличный баг про неправильное сообщение пользователю.
Отредактировано 20.09.2022 14:36 karbofos42 . Предыдущая версия .
Re[8]: Идемпотентность POST - хорошая ли практика?
От: Ночной Смотрящий Россия  
Дата: 20.09.22 18:14
Оценка:
Здравствуйте, karbofos42, Вы писали:

K>Так если я не получу ответ от сервера, то клиент повторно ему запрос на удаление отправит, когда связь восстановится \


И сразу получит 404. А теперь поясни — зачем тебе на клиенте понадобилось знать, удалил ли ты реально или все уже удалено?

K>Кроме удаления по ИД, может быть и удаление по какому-нибудь условию


Удаление по id это тоже удаление по условию, никакой разницы.
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.