Re[11]: Снова про глаголы в REST...
От: vsb Казахстан  
Дата: 20.09.22 07:41
Оценка:
Здравствуйте, Shmj, Вы писали:

S>Такой вариант. PUT 2 раза подряд, параметры 100% одинаковые. Между двумя запросами никаких DELETE и пр. не было, т.е. все чисто. Но в PUT указано состояние Created. Однако когда пришел второй PUT — система в фоновом режиме начала обработку операции и изменила состояние на Processing, что значит заказ клиента начал исполняться и вернуть все в начальное состояние Created, как того требует второй PUT — никоим образом не представляется возможным. Что делать? Просто проигнорите и вернете 200, как бы подразумевая, что клиент использует PUT в качестве создания записи, а раз запись уже создана и хотя состояние изменилось — то все ОК. Или же вернете какую-то ошибку?


Я думаю, в данной ситуации надо возвращать 200. Смысл же в том, чтобы два подряд посланных PUT-а трактовались, как один. Я тут нарушения не вижу.

Кстати у гугла часто логика перехода состояний и тд выносится в Client API. То бишь в данной ситуации сервер сам не начинает никакие обработки, а только по запросу клиента, а в Client API реализована часть логики сервера (эдакая двухзвенка, если можно так выразиться). Минус в том, что без SDK толком ничего не сделать. Мне этот подход кажется сомнительным, но я особо его не продумывал. Может быть в нём и есть смысл.
Отредактировано 20.09.2022 7:43 vsb . Предыдущая версия .
Re[12]: Снова про глаголы в REST...
От: Shmj Ниоткуда  
Дата: 20.09.22 08:11
Оценка:
Здравствуйте, vsb, Вы писали:

vsb>Я думаю, в данной ситуации надо возвращать 200. Смысл же в том, чтобы два подряд посланных PUT-а трактовались, как один. Я тут нарушения не вижу.


Однако же пользователи вашего API могут трактовать PUT не как запрос на создание сущности (вы так трактуете) — а в классическом понимании — как запрос на изменение. И могут поверить вам, что состояние было изменено в соответствие с тем, которое было прислано во втором PUT-запросе. Ведь ошибки не было, значит все ОК.

vsb>Кстати у гугла часто логика перехода состояний и тд выносится в Client API. То бишь в данной ситуации сервер сам не начинает никакие обработки, а только по запросу клиента, а в Client API реализована часть логики сервера (эдакая двухзвенка, если можно так выразиться). Минус в том, что без SDK толком ничего не сделать. Мне этот подход кажется сомнительным, но я особо его не продумывал. Может быть в нём и есть смысл.


Ну т.е. если бы клиент явно отправил запрос PATCH, в котором бы потребовал изменить состояние — то второй запрос PUT — уже должен бы привести к ошибке 409 Conflict?

Быть может правильнее для создания использовать POST, если нужно с ключом идемпотентности? Тогда все становится на свои места. И при попытке повторной отправки с тем же ключом — выдавать ошибку. А PUT использовать только для случаев, когда нет состояния и когда полная замена уместна вне зависимости от состояния.
Отредактировано 20.09.2022 8:31 Shmj . Предыдущая версия .
Re[13]: Снова про глаголы в REST...
От: vsb Казахстан  
Дата: 20.09.22 08:30
Оценка:
Здравствуйте, Shmj, Вы писали:

S>Ну т.е. если бы клиент явно отправил запрос PATCH, в котором бы потребовал изменить состояние — то второй запрос PUT — уже должен бы привести к ошибке 409 Conflict?


Думаю, да. Он же должен в определённой последовательности посылать запросы. И если второй запрос уже ушёл, то первый повторять как-то странно. Если двое пытаются одно и то же делать, тут тоже какая-то фигня получается. В общем мне видится, что в такой ситуации ошибка это правильно, ибо тут или в клиенте баг или два клиента пытаются делать одно и то же, в обоих случаях продолжать это безобразие не нужно.
Re[14]: Снова про глаголы в REST...
От: Shmj Ниоткуда  
Дата: 20.09.22 08:45
Оценка:
Здравствуйте, vsb, Вы писали:

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


Быть может правильнее для создания использовать POST, если нужно с ключом идемпотентности? Тогда все становится на свои места. И при попытке повторной отправки с тем же ключом — выдавать ошибку. А PUT использовать только для случаев, когда нет состояния и когда полная замена уместна вне зависимости от состояния.

Тогда POST будет идемпотентным за счет ключа идемпотентности. PUT будет по-настоящему идемпотентным, как того требует спецификация — без всяких неожиданностей поведения. Но не всегда PUT уместен — если есть состояние — то метод PUT добавлять нельзя, не нужно притворяться. Ну и PATCH будет не идемпотентным, как то и определено спецификацией — если состояние не позволяет — будет возникать ошибка, т.е. зависит от очередности вызовов. PUT от очередности вызовов не зависит — в этом и разница.
Отредактировано 20.09.2022 8:52 Shmj . Предыдущая версия .
Re[2]: Снова про глаголы в REST...
От: Ночной Смотрящий Россия  
Дата: 20.09.22 11:20
Оценка:
Здравствуйте, DiPaolo, Вы писали:

DP>
  • RESTFul API — это не стандарт, не спецификация, т.е. никто не накладывает жестких ограничений

    Тем не менее это набор принципов, которые появились не на пустом месте, и которые без серьезного обоснования лучше не нарушать.

    DP>
  • лучше всего делать так, как удобно вам, т.к. в подавляющем большинстве случаев речь идет об АПИ в рамках одной компании, т.е. для связи бэка и фронта/мобилок

    Нет, лучше всего делать так, как удобно потребителю этого API, даже если он внутри компании. В остальном — см. предыдущую фразу.

    DP>
  • это обычно обходится быстрее и дешевле

    Херак херак и в продакшен?

    DP>, т.к. меньше времени уходит на буквоедство,


    Это не буквоедство, см. первую фразу.
    ... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
  • Re: Снова про глаголы в REST...
    От: Ночной Смотрящий Россия  
    Дата: 20.09.22 11:20
    Оценка: +1
    Здравствуйте, Shmj, Вы писали:

    S>Каноничнее будет так:


    S>
    S>PATCH orders/1
    S>   body: {"state": "confirmed"}
    S>


    Да. Либо, если статус меняется только независимо, лучше будет PUT orders/1/status

    S>Но здесь минус — теряется ясность мысли.


    Не вижу тут никакой потери ясности. Суть запрета глаголов не в каноничности, а в том чтобы заставить рассматривать работу через REST API исключительно как работу с ресурсами. Что, в свою очередь, позволяет этим семантическим приемом избежать значительного количества граблей при разработке сильно распределенных систем. Поэтому "ясность мысли" в REST варианте наоборот приобретается.

    S>Как вы на все это смотрите?


    Строго придерживайся REST API guidelines пока не будет ясного понимания зачем и почему оно так, выйдет дешевле.
    ... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
    Re[2]: Снова про глаголы в REST...
    От: Shmj Ниоткуда  
    Дата: 20.09.22 11:53
    Оценка:
    Здравствуйте, Ночной Смотрящий, Вы писали:

    НС>Не вижу тут никакой потери ясности.


    В случае с глаголом — не нужны лишние сущности в виде состояния, которое может быть только одно — confirmed.

    НС>Строго придерживайся REST API guidelines пока не будет ясного понимания зачем и почему оно так, выйдет дешевле.


    Для примера посмотрите глобальных лидеров — к примеру, PayPal. Как делают они: https://developer.paypal.com/docs/api/orders/v2/#orders_confirm

    Rest API и та же операция — подтвердить заказ. Почему то не в общем виде — а максимально конкретно:

    POST /v2/checkout/orders/{id}/confirm-payment-source


    тут

    Это компания с капитализацией 75 млрд. и которая, по сути, на этом API и зарабатывает. Думаете не хватило денег на хороших спецов или, все-же, такой вариант удобнее?

    Хорошо, давайте пример реального API, где есть операция подтверждения заказа. Любой другой компании. Давайте посмотрим как делает высшая лига.
    Re[3]: Снова про глаголы в REST...
    От: Ночной Смотрящий Россия  
    Дата: 20.09.22 12:28
    Оценка:
    Здравствуйте, Shmj, Вы писали:

    НС>>Не вижу тут никакой потери ясности.

    S>В случае с глаголом — не нужны лишние сущности в виде состояния

    Наоборот, в случае с состоянием не нужны лишние сущности в виде глагола.

    S>, которое может быть только одно — confirmed.


    Нет, еще может быть not confirmed.

    S>Для примера посмотрите глобальных лидеров


    Не самая удачная стратегия. Многие API у лидеров проектировались тогда, когда REST еще не существовал или был в зачаточном состоянии. Так что есть шанс поиметь каку.
    Не боги горшки обжигают, даже у лидеров.

    S>Хорошо, давайте пример реального API, где есть операция подтверждения заказа. Любой другой компании. Давайте посмотрим как делает высшая лига.


    Гугль для тебя достаточно авторитетен? https://developers.google.com/shopping-content/reference/rest/v2.1/orders/acknowledge
    Вот похожая штука у МС — https://learn.microsoft.com/en-us/partner-center/develop/confirm-customer-consent-customer-agreement
    Вот похожая у амазона — https://developer-docs.amazon.com/sp-api/docs/orders-api-v0-reference#post-ordersv0ordersorderidshipment
    ... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
    Re[4]: Снова про глаголы в REST...
    От: Shmj Ниоткуда  
    Дата: 20.09.22 13:06
    Оценка:
    Здравствуйте, Ночной Смотрящий, Вы писали:

    S>>, которое может быть только одно — confirmed.

    НС>Нет, еще может быть not confirmed.

    Нет, не может — только подтвердить клиент может и ничего другого. Отменить подтверждение — нельзя.

    S>>Хорошо, давайте пример реального API, где есть операция подтверждения заказа. Любой другой компании. Давайте посмотрим как делает высшая лига.


    НС>Гугль для тебя достаточно авторитетен? https://developers.google.com/shopping-content/reference/rest/v2.1/orders/acknowledge


    Вполне. Вот вам пример: https://developers.google.com/shopping-content/reference/rest/v2.1/orders/cancel

    POST https://shoppingcontent.googleapis.com/content/v2.1/{merchantId}/orders/{orderId}/cancel


    — глагол, притом методом POST. А могли бы PATCH и в теле state=cancelled.

    Притом это версия API свежая — 2.1, нельзя списать на древность. PayPal тоже API постоянно обновляет — я вам дал v2 а не древнее.

    Как видите — часто удобно сделать глаголом, чтобы не нарушалась ясность мысли. Т.е. здесь при вызове конкретное действие. Просто и ясно.

    НС>Вот похожая штука у МС — https://learn.microsoft.com/en-us/partner-center/develop/confirm-customer-consent-customer-agreement


    Тут да, MS сделали все строго — хотел найти и не смог придраться.

    НС>Вот похожая у амазона — https://developer-docs.amazon.com/sp-api/docs/orders-api-v0-reference#post-ordersv0ordersorderidshipment




    POST /shipping/v1/shipments/{shipmentId}/cancel
    Re[5]: Снова про глаголы в REST...
    От: Ночной Смотрящий Россия  
    Дата: 20.09.22 18:14
    Оценка: +2
    Здравствуйте, Shmj, Вы писали:

    S>>>, которое может быть только одно — confirmed.

    НС>>Нет, еще может быть not confirmed.
    S>Нет, не может — только подтвердить клиент может и ничего другого. Отменить подтверждение — нельзя.

    Ты путаешь возможные состояния и ограничения на их изменение. Это не одно и тоже.
    Проблема все та же — ты продолжаешь мыслить глаголами. Клиент подтверждает, клиент отменяет. А REST это про состояние ресурсов и его изменение (representational state transfer).

    НС>>Гугль для тебя достаточно авторитетен? https://developers.google.com/shopping-content/reference/rest/v2.1/orders/acknowledge

    S>Вполне. Вот вам пример: https://developers.google.com/shopping-content/reference/rest/v2.1/orders/cancel

    Ты просил пример, зачем ты вытаскиваешь другие кейсы? Хочешь показать что дизайн реста косячат даже в крупных корпорациях? Так никто в том и не сомневается.
    Кроме того, конкретно cancel это и существительное тоже, короткая форма cancellation.

    S>Как видите — часто удобно сделать глаголом, чтобы не нарушалась ясность мысли.


    Ты как определяешь что "ясность мысли" нарушилась? Есть какой то объективный критерий, или это твоя вкусовщина?
    ... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
    Подождите ...
    Wait...
    Пока на собственное сообщение не было ответов, его можно удалить.