REST API Style Guide: Alias и Action-эндпоинты

Alias-сегменты REST API: me, latest, default. Action-эндпоинты для доменных команд.

REST API alias 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"
}

Если параметров нет -- пустое тело допустимо.