Принципы синхронного API
Приложение отправляет запрос получателю и останавливает работу, пока ждёт ответа. Такой подход применяют, если нужно сохранить порядок вызовов систем.
-
Уровень 0
ЛегасиИспользуем XML, единственный URI и HTTP-метод — обычно POST.
-
Уровень 1
РесурсыКаждому ресурсу отдельный эндпоинт, можно перейти на JSON.
-
Уровень 2
HTTP-глаголыИспользуем правильные HTTP-методы и статус-коды, поддерживаем фильтрацию, пагинацию, поиск, сортировку и версионирование.
Цель — достичь 2 уровня на всех канонических API.
Построение URI
Используем kebab-case
для URL и camelCase
для параметров и атрибутов.
- У каждого ресурса свой эндпоинт.
- Название ресурса всегда во множественном числе.
- Если ресурс относится к другому, используем вложенность.
/customers/{id}/addresses
все адреса конкретного кастомера - Максимальная вложенность — 1.
/suppliers/{id}/products/{id}/media/{id}
слишком глубоко - Можно использовать единственное число там, где других таких же предметов быть не может.
-
/delivery/v1/products
не бывает иных обьектовdelivery
Хорошие примеры
/customers
все кастомеры
/customers/{id}/addresses
все адреса конкретного кастомера
/products?supplierId={supplierId}
список продуктов по поставщику
/products/{id}
детали определённого продукта
/products/{id}/media
список медиа одного продукта
Умеренная гранулярность.
Не надо возвращать информацию, которую не спрашивали.
/clients/1/address
{
“road”: “121 rue Chanzy”,
“city”: “Hellemmes”,
“country”: “France”,
“age”: 22 — возраст здесь лишний
}
Используем суррогатные ключи правильно.
Суррогатный ключ — это ключ, искусственно сгенерированный системой. Не путать с первичным ключом базы данных. Ещё бывают натуральные ключи, сформированные из атрибутов, существующих в реальной жизни.
В REST API, вместо первичных ключей базы данных, лучше использовать натуральные ключи — если БД поменяется, у нас могут быть проблемы с интеграцией, да и вообще это не секьюрно.
Хорошие примеры
/some-resource?tag=green
натуральный ключ green понятен пользователям
/customer/0012345
кастомер ID — суррогатный ключ для этого API
Плохие примеры
/some-resource?tag=1
вернуть всё с тегом green через его id «1»
/customer/23dde7-e89b-12d3-a456-4265
кастомер ID это UUID, сгенерированный БД
HTTP-методы
- GET получить
- POST создать
- PUT перезаписать
- PATCH частично обновить
- DELETE удалить
- OPTIONS вернуть все HTTP-методы, доступные для эндпоинта
Когда что-то не подходит, используем
- POST метод
- action-глаголы
- паттерн
/collections/{resource}:{action}
Пример
POST /users/123:subscribe
URL параметры запросов
Заголовки
Содержит технические параметры или элементы контекста.
Content-Type: application/json
ADEO-BU-CODE: 10
Path-параметры
Эти параметры — часть URL. С их помощью можно понять, к какому ресурсу мы обращаемся.
/product/{id}/stocks
Query-параметры
Позволяют фильтровать и сортировать запросы.
Хорошие примеры
/products?q=Luke+man
поиск продукта по тексту
/products?storeId=35
фильтрация продуктов по параметру магазина 35
/products?sort=name&desc=age,id
сортировка по возростанию name и убыванию age, а затем id.
Пагинация
- Пагинация по номеру страницы
?page=2&perPage=100
- Пагинация по курсору
?limit=25&before=ZDMyNz6yORI3OTLo
Не стоит хранить курсоры: они быстро становятся невалидными из-за вставки или удаления элементов.
- Пагинация через оффсет & лимит
?limit=25&offset=50
- Пагинация через временные метки
?limit=25&since=1364849754
В качестве ключа для пагинации по временным меткам используем Unix timestamp.
Ответ: Общие правила
- Структура ответа HTTP не должна зависеть от структуры БД
- Все поля должны быть понятны с бизнес-точки зрения
- Все наименования полей должны быть простыми, интуитивными и согласованными
- Лучше не использовать технические термины и специфические термины систем.
Ответ: Статус коды
Все методы
- Для всех эндпоинтов необходимо возвращать статус-коды.
- Каждый сервис потенциально должен уметь возвращать 500.
- Каждый сервис, который требует минимум один обязательный параметр на вход, должен уметь возвращать 400 с описанием.
- Каждый секьюрный сервис должен уметь возвращать 401.
GET
- Если данных нет, каждый сервис должен возвращать 404.
- Каждая коллекция должна вернуть 200, если возвращается полностью.
- Каждая коллекция должна вернуть 206, если возвращается частично.
204 или 404
Есть небольшой спор: какой код возвращать, когда URL корректный, но информация не найдена? Если информация запрашивалась по ключу, мы рекомендуем возвращать 404, если информация не найдена после фильтрации или поиска по параметрам — 204.
POST
- Возвращаем 201 после создания ресурса.
PUT & PATCH:
- Возвращаем 200 после обновления ресурса.
DELETE
- Возвращаем 204 после успешно удалённой информации.
Ответ: Коды ошибок
Вместе с HTTP кодами ответов в теле необходимо указать код ошибки. Это позволит потребителю понять, что именно пошло не так, и правильно среагировать. Ответ с ошибкой может содержать бизнес код ошибки с описанием причины падения. Все эти коды должны быть описаны в документации API.
Один из популярных форматов описания ошибок JSON-API:
{
"errors": [{
"code": "ERR-01234",
"title": "OAuth Exception",
"details": "Session has expired at unix time 1385243766.",
"links": {
"about": "http://example.com/docs/errors/#ERR-01234"
}
}]
}
Кусок кода в формате сваггера с описанием кода ответа и кода ошибок:
{
Responses:
”200”:
description: mySuccessResponse
Schema:
type: array
Items:
$ref: “#/definitions/Pet”,
“400”:
description: Invalid status value
}
Ответы: Формат данных
E.164 – Телефонный номер
[+][код страны][код местности][местный номер]
- + — знак плюса
- код страны — международный код страны
- код местности — код местности без 0 в начале
- местный номер — местный номер телефона
ISO 639 – Язык
- eng – Английский
- fra – Французский
- rus – Русский
ISO 3166-1 — Язык
- Russia (Russian Federation) Россия RU RUS 643
- France Франция FR FRA 250
- China Китай CN CHN 156
ISO 8601 – Дата
- YYYY-MM 2020-06
- YYYYMMDD 20200602
- YYYY-MM-DDThh:mm:ss±hh 2020-06-02T15:22:00+00:00
ISO 4217 — Деньги
- EUR 978 – Евро
- USD 840 – Доллар США
- KZT 398 – Тенге
- BYN 933 – Беларусский Рубль
UCUM – Меры измерения
Все меры измерения в UCUM specification.