1
0
mirror of https://github.com/twirl/The-API-Book.git synced 2025-08-10 21:51:42 +02:00

corrections

This commit is contained in:
Sergey Konstantinov
2022-09-13 23:09:08 +03:00
parent 385f529ae9
commit 165332c92e
3 changed files with 8 additions and 1140 deletions

View File

@@ -123,6 +123,7 @@ pre {
code {
white-space: nowrap;
font-size: 80%;
}
.img-wrapper img {
@@ -140,7 +141,6 @@ pre {
box-sizing: border-box;
page-break-inside: avoid;
overflow-x: auto;
font-size: 80%;
}
img:not(.cc-by-nc-img) {

View File

@@ -998,7 +998,7 @@ POST /v1/orders/
PATCH /v1/orders/{id}
{
"items": [null, {
"volume": "800ml"
"volume": "800ml"
}]
}
@@ -1022,7 +1022,6 @@ PATCH /v1/orders/{id}
**Лучше**: разделить эндпойнты. Редактируемые поля группируются и выносятся в отдельный эндпойнт. Этот подход также хорошо согласуется [с принципом декомпозиции](#chapter-10), который мы рассматривали в предыдущем разделе.
```
```
// Создаёт заказ из двух напитков
POST /v1/orders/
@@ -1050,6 +1049,7 @@ POST /v1/orders/
]
}
```
```
// Изменяет параметры заказа
PUT /v1/orders/{id}/parameters
@@ -1057,6 +1057,7 @@ PUT /v1/orders/{id}/parameters
{ "delivery_address" }
```
```
// Частично перезаписывает заказ
// обновляет объём второго напитка
@@ -1065,15 +1066,16 @@ PUT /v1/orders/{id}/items/{item_id}
{ "recipe", "volume", "milk_type" }
```
```
Теперь для удаления `volume` достаточно *не* передавать его в `PUT items/{item_id}`. Этот подход также позволяет отделить неизменяемые и вычисляемые поля (`created_at` и `status`) от изменяемых, не создавая двусмысленных ситуаций (что произойдёт, если клиент попытается изменить `created_at`?). В этом подходе также можно в ответах операций `PUT` возвращать объект заказа целиком (однако следует использовать какую-то конвенцию именования), а не только изменённые суб-объекты.
**NB**: при декомпозиции эндпойнтов велик соблазн провести границу так, чтобы разделить изменяемые и неизменяемые данные. Тогда последние можно объявить кэшируемыми условно вечно и вообще не думать над проблемами пагинации и формата обновления. На бумаге план выглядит отлично, однако с ростом API неизменяемые данные частенько перестают быть таковыми, и вся концепция не только перестаёт работать, но и выглядит как плохой дизайн. Мы скорее рекомендуем объявлять данные иммутабельными в одном из двух случаев: либо (1) они действительно не могут стать изменяемыми без слома обратной совместимости, либо (2) ссылка на ресурс (например, на изображение) поступает через API же, и вы обладаете возможностью сделать эти ссылки персистентными (т.е. при необходимости обновить изображение будете генерировать новую ссылку, а не перезаписывать контент по старой ссылке).
**Ещё лучше**: разработать формат описания атомарных изменений.
```
POST /v1/order/changes
X-Idempotency-Token: <см. следующий раздел>
X-Idempotency-Token: <токен идемпотентности>
{
"changes": [{
"type": "set",
@@ -1128,7 +1130,7 @@ X-Idempotency-Token: <см. следующий раздел>
Следует иметь в виду, что явной передачи локации может оказаться недостаточно, поскольку в мире существуют территориальные конфликты и спорные территории. Каким образом API должен себя вести при попадании координат пользователя на такие территории — вопрос, к сожалению, в первую очередь юридический. Автору этой книги приходилось как-то разрабатывать API, в котором пришлось вводить концепцию «территория государства A по мнению официальных органов государства Б».
**Важно**: различайте локализацию для конечного пользователя и локализацию для разработчика. В примере из п. 19 сообщение `localized_message` адресовано пользователю — его должно показать приложение, если в коде обработка такой ошибки не предусмотрена. Это сообщение должно быть написано на указанном в запросе языке и отформатировано согласно правилам локации пользователя. А вот сообщение `details.checks_failed[].message` написано не для пользователя, а для разработчика, который будет разбираться с проблемой. Соответственно, написано и отформатировано оно должно быть понятным для разработчика образом — что, скорее всего, означает «на английском языке», т.к. английский де-факто является стандартом в мире разработки программного обеспечения.
**Важно**: различайте локализацию для конечного пользователя и локализацию для разработчика. В примере из п. 12 сообщение `localized_message` адресовано пользователю — его должно показать приложение, если в коде обработка такой ошибки не предусмотрена. Это сообщение должно быть написано на указанном в запросе языке и отформатировано согласно правилам локации пользователя. А вот сообщение `details.checks_failed[].message` написано не для пользователя, а для разработчика, который будет разбираться с проблемой. Соответственно, написано и отформатировано оно должно быть понятным для разработчика образом — что, скорее всего, означает «на английском языке», т.к. английский де-факто является стандартом в мире разработки программного обеспечения.
Следует отметить, что индикация, какие сообщения следует показать пользователю, а какие написаны для разработчика, должна, разумеется, быть явной конвенцией вашего API. В примере для этого используется префикс `localized_`.

File diff suppressed because it is too large Load Diff