Гайды
Принципы REST API: HATEOAS и версионирование
Ресурсы и HTTP-методы, коды ответа, гиперссылки в JSON, версии в URL и заголовках, идемпотентность и Problem Details.
~10 мин чтения
Принципы REST API: HATEOAS и версионирование
REST (Representational State Transfer) — стиль архитектуры, а не один стандарт RFC. На практике «RESTful API» — ресурсы, HTTP-методы, коды состояния, идемпотентность там, где ожидается. HATEOAS и версионирование — зрелые темы для публичных долгоживущих API. Сравнение с GraphQL — GraphQL vs REST; машиночитаемый контракт — OpenAPI.
1. Ресурсы и URI
| Метод | Пример | Смысл |
|---|---|---|
| GET | /orders/42 | Получить представление |
| POST | /orders | Создать (часто сервер задаёт id) |
| PUT | /orders/42 | Заменить целиком (идемпотентно) |
| PATCH | /orders/42 | Частичное обновление |
| DELETE | /orders/42 | Удалить (идемпотентно в смысле состояния после повтора) |
Имена — существительные; глаголы — в query или подресурсах (/orders/42/cancel обсуждаемо как sub-resource action).
2. Коды ответа
Используйте 201 Created с Location, 204 No Content, 409 Conflict, 422 Unprocessable Entity (валидация), 429 Too Many Requests. Не отдавайте всё как 200 с {error: ...} без веской причины.
3. HATEOAS (Hypermedia as the Engine of Application State)
Ответ содержит ссылки на следующие допустимые действия (HAL, JSON-LD, проблемный _links в custom JSON):
{
"id": 42,
"status": "pending",
"_links": {
"self": { "href": "/orders/42" },
"pay": { "href": "/orders/42/payment", "method": "POST" },
"cancel": { "href": "/orders/42", "method": "DELETE" }
}
}
Клиент меньше хардкодит URL логики; цена — размер ответа и сложность клиентских библиотек. Для внутренних API часто достаточно стабильных путей без гипермедиа.
4. Версионирование
| Подход | Плюсы | Минусы |
|---|---|---|
/v1/ в URL | Просто кэшировать и документировать | Засорение путей |
Заголовок Accept с vendor MIME | Чистые URL | Сложнее для браузерных ссылок |
Query ?version=1 | Редко | Кэш-хаос |
Политика: не ломать существующих клиентов; deprecated поля — с датой отключения; мажорная версия — новый префикс или контракт.
5. Идемпотентность и безопасность
- PUT/DELETE клиенты могут повторять при сетевых сбоях — сервер должен вести себя предсказуемо.
- POST создания — используйте Idempotency-Key заголовок для защиты от дублей оплаты/заказа.
6. Пагинация
Offset/limit — просто, плохо на больших смещениях. Cursor (keyset) — стабильнее для лент; закодируйте курсор opaque.
7. Ошибки: Problem Details (RFC 7807)
Единый формат type, title, status, detail, instance упрощает поддержку и клиентов. В OpenAPI — вынесите в components/responses — см. OpenAPI-гайд.
8. Условные запросы и конкуренция
ETag / Last-Modified на GET позволяют клиенту слать If-None-Match / If-Modified-Since и получать 304 Not Modified — экономия трафика и CDN. Для PATCH/PUT используйте If-Match: "<etag>" как optimistic lock: при рассинхроне версий отвечайте 412 Precondition Failed или 409 Conflict по выбранной политике.
9. Чек-лист
- Ресурсная модель согласована с доменом.
- Коды HTTP осмысленны.
- Версия и deprecation задокументированы.
- HATEOAS — только если клиенты реально его потребляют.
Дальше: Django REST Framework · тег REST