Информация об изменениях

Сообщение Re[3]: Возврат ошибок в API от 04.09.2019 19:13

Изменено 04.09.2019 19:44 RushDevion

Re[3]: Возврат ошибок в API
МР>Если не сложно, проясните этот момент.

Попробую.
Прежде всего, идеологически это соответствует описанию статус-кодов HTTP-протокола.
И там много чисто HTTP-шных нюансов. Например, 200 ответы по-умолчанию кэшируется, а 201/202 — нет.
Кроме того, клиенту никто не мешает просто интерпретировать любой 2xx код как успешный.

С практической же точки зрения, попробую объяснить на примерах:

1. 200 vs 202 (Accepted)
POST /api/payments { id, amount, operationType }
Сервер в зависимости от параметров платежа (сумма, тип) и текущего состояния системы (высокая нагрузка, конкретный провайдер платежа лежит и т.п.) может либо исполнить платеж сразу, либо отложить его на потом.
Поэтому:
200 OK — исполнили сразу, результат вернули, его можно сразу прочитать и отобразить пользователю.
202 Accepted — приняли к исполнению, исполним позже. Клиенту можно не читать body, а сразу идти на GET /api/payments/{id} и проверять статус там.

2. 200 vs 201 (Created)
POST /api/payments { id, amount, operationType }
ID платежа определяет клиент (скажем, это GUID).
А мы со своей стороны гарантируем идемпотентность операции создания, т.е.
мы говорим: "если ты будешь пытаться создать платеж с одним и тем же id много раз, то для нас это нормально".
По HTTP протоколу POST запросы не идемпотентные, но это бывает нужно, если, например у нас слабый канал и клиент реализует какую-то политику ретрая.
Или клиент пропихивает платежи из своей системы в нашу в несколько потоков/процессов.
В этом случае:
201 (Created) — клиент уверен, что это именно он создал платеж. Можно, например, обновлять балансы в своей локальной системе.
200 OK — такой платеж уже есть, но его создали не мы. Просто игнорируем.

Если бы мы возвращали чисто 200, нам бы пришлось как-то менять модель платежа (добавлять какие-то доп. поля/признаки) для обработки такой ситуации, что как-то не очень чисто.

3. 200 vs 204 (No Content)
POST /api/articles/{id} => [ content ]
Допустим мы пишем редактор постов на wiki для такой API-шки (POST соответствует сохранению).
Тогда у нас возможны варианты:
200 OK — твои данные сохранились. Но, похоже, кто-то делал изменения в других частях статьи, и мы их смержили. Прочитай новое тело статьи из тела ответа и обнови UI.
204 OK — твои данные сохранили. Статья на сервере такая же, как локальная, поэтому контента мы тебе не шлем.
Re[3]: Возврат ошибок в API
МР>Если не сложно, проясните этот момент.

Попробую.
Прежде всего, идеологически это соответствует описанию статус-кодов HTTP-протокола.
И там много чисто HTTP-шных нюансов. Например, 200 ответы по-умолчанию кэшируется, а 201/202 — нет.
Кроме того, клиенту никто не мешает просто интерпретировать любой 2xx код как успешный.

С практической же точки зрения, попробую объяснить на примерах:

1. 200 vs 202 (Accepted)
POST /api/payments { id, amount, operationType }
Сервер в зависимости от параметров платежа (сумма, тип) и текущего состояния системы (высокая нагрузка, конкретный провайдер платежа лежит и т.п.) может либо исполнить платеж сразу, либо отложить его на потом.
Поэтому:
200 OK — исполнили сразу, результат вернули, его можно сразу прочитать и отобразить пользователю.
202 Accepted — приняли к исполнению, исполним позже. Клиенту можно не читать body, а сразу идти на GET /api/payments/{id} и проверять статус там.

2. 200 vs 201 (Created)
POST /api/payments { id, amount, operationType }
ID платежа определяет клиент (скажем, это GUID).
А мы со своей стороны гарантируем идемпотентность операции создания, т.е.
мы говорим: "если ты будешь пытаться создать платеж с одним и тем же id много раз, то для нас это нормально".
По HTTP протоколу POST запросы не идемпотентные, но это бывает нужно, если, например у нас слабый канал и клиент реализует какую-то политику ретрая.
Или клиент пропихивает платежи из своей системы в нашу в несколько потоков/процессов.
В этом случае:
201 (Created) — клиент уверен, что это именно он создал платеж. Можно, например, обновлять балансы в своей локальной системе.
200 OK — такой платеж уже есть, но его создали не мы. Просто игнорируем.

Если бы мы возвращали чисто 200, нам бы пришлось как-то менять модель платежа (добавлять какие-то доп. поля/признаки) для обработки такой ситуации, что как-то не очень чисто.

3. 200 vs 204 (No Content)
POST /api/articles/{id} => [ content ]
Допустим мы пишем редактор постов на wiki для такой API-шки (POST соответствует сохранению).
Тогда у нас возможны варианты:
200 OK — твои данные сохранились. Но, похоже, кто-то делал изменения в других частях статьи, и мы их смержили. Прочитай новое тело статьи из тела ответа и обнови UI.
204 OK — твои данные сохранили. Статья на сервере такая же, как локальная, поэтому контента мы тебе не шлем.