Здравствуйте, Shmj, Вы писали:
S>Такой вариант. PUT 2 раза подряд, параметры 100% одинаковые. Между двумя запросами никаких DELETE и пр. не было, т.е. все чисто. Но в PUT указано состояние Created. Однако когда пришел второй PUT — система в фоновом режиме начала обработку операции и изменила состояние на Processing, что значит заказ клиента начал исполняться и вернуть все в начальное состояние Created, как того требует второй PUT — никоим образом не представляется возможным. Что делать? Просто проигнорите и вернете 200, как бы подразумевая, что клиент использует PUT в качестве создания записи, а раз запись уже создана и хотя состояние изменилось — то все ОК. Или же вернете какую-то ошибку?
Я думаю, в данной ситуации надо возвращать 200. Смысл же в том, чтобы два подряд посланных PUT-а трактовались, как один. Я тут нарушения не вижу.
Кстати у гугла часто логика перехода состояний и тд выносится в Client API. То бишь в данной ситуации сервер сам не начинает никакие обработки, а только по запросу клиента, а в Client API реализована часть логики сервера (эдакая двухзвенка, если можно так выразиться). Минус в том, что без SDK толком ничего не сделать. Мне этот подход кажется сомнительным, но я особо его не продумывал. Может быть в нём и есть смысл.
Здравствуйте, vsb, Вы писали:
vsb>Я думаю, в данной ситуации надо возвращать 200. Смысл же в том, чтобы два подряд посланных PUT-а трактовались, как один. Я тут нарушения не вижу.
Однако же пользователи вашего API могут трактовать PUT не как запрос на создание сущности (вы так трактуете) — а в классическом понимании — как запрос на изменение. И могут поверить вам, что состояние было изменено в соответствие с тем, которое было прислано во втором PUT-запросе. Ведь ошибки не было, значит все ОК.
vsb>Кстати у гугла часто логика перехода состояний и тд выносится в Client API. То бишь в данной ситуации сервер сам не начинает никакие обработки, а только по запросу клиента, а в Client API реализована часть логики сервера (эдакая двухзвенка, если можно так выразиться). Минус в том, что без SDK толком ничего не сделать. Мне этот подход кажется сомнительным, но я особо его не продумывал. Может быть в нём и есть смысл.
Ну т.е. если бы клиент явно отправил запрос PATCH, в котором бы потребовал изменить состояние — то второй запрос PUT — уже должен бы привести к ошибке 409 Conflict?
Быть может правильнее для создания использовать POST, если нужно с ключом идемпотентности? Тогда все становится на свои места. И при попытке повторной отправки с тем же ключом — выдавать ошибку. А PUT использовать только для случаев, когда нет состояния и когда полная замена уместна вне зависимости от состояния.
Здравствуйте, Shmj, Вы писали:
S>Ну т.е. если бы клиент явно отправил запрос PATCH, в котором бы потребовал изменить состояние — то второй запрос PUT — уже должен бы привести к ошибке 409 Conflict?
Думаю, да. Он же должен в определённой последовательности посылать запросы. И если второй запрос уже ушёл, то первый повторять как-то странно. Если двое пытаются одно и то же делать, тут тоже какая-то фигня получается. В общем мне видится, что в такой ситуации ошибка это правильно, ибо тут или в клиенте баг или два клиента пытаются делать одно и то же, в обоих случаях продолжать это безобразие не нужно.
Здравствуйте, vsb, Вы писали:
vsb>Думаю, да. Он же должен в определённой последовательности посылать запросы. И если второй запрос уже ушёл, то первый повторять как-то странно. Если двое пытаются одно и то же делать, тут тоже какая-то фигня получается. В общем мне видится, что в такой ситуации ошибка это правильно, ибо тут или в клиенте баг или два клиента пытаются делать одно и то же, в обоих случаях продолжать это безобразие не нужно.
Быть может правильнее для создания использовать POST, если нужно с ключом идемпотентности? Тогда все становится на свои места. И при попытке повторной отправки с тем же ключом — выдавать ошибку. А PUT использовать только для случаев, когда нет состояния и когда полная замена уместна вне зависимости от состояния.
Тогда POST будет идемпотентным за счет ключа идемпотентности. PUT будет по-настоящему идемпотентным, как того требует спецификация — без всяких неожиданностей поведения. Но не всегда PUT уместен — если есть состояние — то метод PUT добавлять нельзя, не нужно притворяться. Ну и PATCH будет не идемпотентным, как то и определено спецификацией — если состояние не позволяет — будет возникать ошибка, т.е. зависит от очередности вызовов. PUT от очередности вызовов не зависит — в этом и разница.
Здравствуйте, DiPaolo, Вы писали:
DP> RESTFul API — это не стандарт, не спецификация, т.е. никто не накладывает жестких ограничений
Тем не менее это набор принципов, которые появились не на пустом месте, и которые без серьезного обоснования лучше не нарушать.
DP> лучше всего делать так, как удобно вам, т.к. в подавляющем большинстве случаев речь идет об АПИ в рамках одной компании, т.е. для связи бэка и фронта/мобилок
Нет, лучше всего делать так, как удобно потребителю этого API, даже если он внутри компании. В остальном — см. предыдущую фразу.
DP> это обычно обходится быстрее и дешевле
Херак херак и в продакшен?
DP>, т.к. меньше времени уходит на буквоедство,
Да. Либо, если статус меняется только независимо, лучше будет PUT orders/1/status
S>Но здесь минус — теряется ясность мысли.
Не вижу тут никакой потери ясности. Суть запрета глаголов не в каноничности, а в том чтобы заставить рассматривать работу через REST API исключительно как работу с ресурсами. Что, в свою очередь, позволяет этим семантическим приемом избежать значительного количества граблей при разработке сильно распределенных систем. Поэтому "ясность мысли" в REST варианте наоборот приобретается.
S>Как вы на все это смотрите?
Строго придерживайся REST API guidelines пока не будет ясного понимания зачем и почему оно так, выйдет дешевле.
Здравствуйте, Ночной Смотрящий, Вы писали:
НС>Не вижу тут никакой потери ясности.
В случае с глаголом — не нужны лишние сущности в виде состояния, которое может быть только одно — confirmed.
НС>Строго придерживайся REST API guidelines пока не будет ясного понимания зачем и почему оно так, выйдет дешевле.
Это компания с капитализацией 75 млрд. и которая, по сути, на этом API и зарабатывает. Думаете не хватило денег на хороших спецов или, все-же, такой вариант удобнее?
Хорошо, давайте пример реального API, где есть операция подтверждения заказа. Любой другой компании. Давайте посмотрим как делает высшая лига.
Здравствуйте, Shmj, Вы писали:
НС>>Не вижу тут никакой потери ясности. S>В случае с глаголом — не нужны лишние сущности в виде состояния
Наоборот, в случае с состоянием не нужны лишние сущности в виде глагола.
S>, которое может быть только одно — confirmed.
Нет, еще может быть not confirmed.
S>Для примера посмотрите глобальных лидеров
Не самая удачная стратегия. Многие API у лидеров проектировались тогда, когда REST еще не существовал или был в зачаточном состоянии. Так что есть шанс поиметь каку.
Не боги горшки обжигают, даже у лидеров.
S>Хорошо, давайте пример реального API, где есть операция подтверждения заказа. Любой другой компании. Давайте посмотрим как делает высшая лига.
Здравствуйте, Ночной Смотрящий, Вы писали:
S>>, которое может быть только одно — confirmed. НС>Нет, еще может быть not confirmed.
Нет, не может — только подтвердить клиент может и ничего другого. Отменить подтверждение — нельзя.
S>>Хорошо, давайте пример реального API, где есть операция подтверждения заказа. Любой другой компании. Давайте посмотрим как делает высшая лига.
НС>Гугль для тебя достаточно авторитетен? https://developers.google.com/shopping-content/reference/rest/v2.1/orders/acknowledge
Здравствуйте, Shmj, Вы писали:
S>>>, которое может быть только одно — confirmed. НС>>Нет, еще может быть not confirmed. S>Нет, не может — только подтвердить клиент может и ничего другого. Отменить подтверждение — нельзя.
Ты просил пример, зачем ты вытаскиваешь другие кейсы? Хочешь показать что дизайн реста косячат даже в крупных корпорациях? Так никто в том и не сомневается.
Кроме того, конкретно cancel это и существительное тоже, короткая форма cancellation.
S>Как видите — часто удобно сделать глаголом, чтобы не нарушалась ясность мысли.
Ты как определяешь что "ясность мысли" нарушилась? Есть какой то объективный критерий, или это твоя вкусовщина?