REST API Style Guide: Alias и Action-эндпоинты
Alias-сегменты REST API: me, latest, default. Action-эндпоинты для доменных команд.
REST API alias action эндпоинты: 6. Alias-сегменты (зарезервированные слова вместо ID)
REST API alias action эндпоинты — в ряде случаев вместо конкретного идентификатора в path используется зарезервированное слово-алиас. Это серверный shortcut, который разрешается в конкретный ресурс на основе контекста (токен, сессия, бизнес-логика).
6.1. Идентификация текущего пользователя
me--GET /api/v1/users/me-- текущий аутентифицированный пользовательme--PATCH /api/v1/users/me-- редактирование своего профиляme--POST /api/v1/users/me/offers/{id}-- связать ресурс с текущим пользователем (many-to-many)
me -- самый распространенный alias. Альтернативы self, current-user встречаются, но me -- де-факто стандарт (GitHub API, Google API, Spotify API, Microsoft Graph).
GET /api/v1/users/me -- правильно (де-факто стандарт)
GET /api/v1/users/self -- допустимо, но менее распространено
GET /api/v1/users/current -- допустимо, но менее распространено
GET /api/v1/me -- неправильно (me -- не ресурс, а alias для users/{id})
Когда users/me нужен, а когда нет:
Если API работает в контексте аутентифицированного пользователя и ресурс принадлежит только ему -- users/me в пути избыточен. Контекст владельца берётся из токена:
GET /api/v1/orders -- правильно (заказы текущего пользователя из контекста токена)
GET /api/v1/users/me/orders -- избыточно (orders и так "его")
users/me нужен когда:
- Запрашиваются данные самого пользователя --
GET /api/v1/users/me,PATCH /api/v1/users/me - Связка many-to-many между пользователем и другим ресурсом --
POST /api/v1/users/me/offers/{id}(принять оферту),DELETE /api/v1/users/me/offers/{id}(отвязать) - Ресурс существует и вне контекста пользователя, но нужна фильтрация "мои" --
GET /api/v1/users/me/notifications
6.2. Временные и порядковые alias'ы
latest--GET /api/v1/deployments/latest-- последний деплойcurrent--GET /api/v1/subscriptions/current-- текущая активная подпискаnext--GET /api/v1/invoices/next-- следующий (предстоящий) счетprevious--GET /api/v1/billing-periods/previous-- предыдущий расчетный периодfirst--GET /api/v1/versions/first-- самая первая версияlast--GET /api/v1/transactions/last-- последняя транзакция (синоним latest)
6.3. Логические alias'ы (выбор по бизнес-признаку)
default--GET /api/v1/payment-methods/default-- платежный метод по умолчаниюprimary--GET /api/v1/addresses/primary-- основной адресactive--GET /api/v1/plans/active-- текущий активный тарифdraft--GET /api/v1/documents/draft-- черновик (если singleton в контексте)
7. Action-эндпоинты (команды)
Не все операции укладываются в CRUD. Доменные команды, меняющие состояние агрегата, оформляются как action-эндпоинты.
7.1. Формат: ресурс + действие
POST /api/v1/orders/{id}/confirm
POST /api/v1/orders/{id}/cancel
POST /api/v1/orders/{id}/ship
POST /api/v1/orders/{id}/refund
7.2. Действие -- глагол в инфинитиве
/orders/{id}/confirm -- правильно
/orders/{id}/confirmation -- неправильно (существительное)
/orders/{id}/confirmed -- неправильно (причастие)
7.3. Метод для действий -- POST
Action-эндпоинты всегда используют POST. Даже если операция идемпотентна по факту (повторный confirm не изменит состояние), она является командой, а не заменой ресурса:
POST /api/v1/orders/{id}/confirm -- правильно
POST /api/v1/orders/{id}/cancel -- правильно
POST /api/v1/orders/{id}/refund -- правильно
PUT /api/v1/orders/{id}/confirm -- неправильно (PUT = замена ресурса, не команда)
7.4. Тело запроса для действий
Если действие требует параметров -- передавайте в теле:
POST /api/v1/orders/{id}/ship
Content-Type: application/json
{
"trackingNumber": "TR-123456",
"carrier": "DHL"
}
Если параметров нет -- пустое тело допустимо.