Гайды

Принципы 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):

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