Опирается на правила: R-ALIAS-1..3, R-ACT-1..4 и X-коды из REST API Style Guide → раздел Alias и Action-эндпоинты.

Важно знать

  • me — только когда endpoint может принять и свой, и чужой ID (admin scope).
  • Граница me: «может ли супер-админ обратиться по другому ID?» Да → me нужен.
  • Временные/порядковые alias (latest, current, next, previous) — для singleton-выборки.
  • Логические alias (default, primary, active, draft) — для singleton-выборки.
  • Action-эндпоинты для команд, не укладывающихся в CRUD: POST /orders/{id}/confirm.
  • Имя действия — глагол в инфинитиве (confirm, не confirmation или confirmed).
  • Метод action — всегда POST, даже если операция идемпотентна.
  • /api/v1/me без users/ префикса — запрещён.

CRUD не покрывает все доменные операции. UCP формулирует два расширения: alias-сегменты для shortcut-выборки (users/me, deployments/latest) и action-эндпоинты для команд, изменяющих state агрегата (orders/{id}/confirm).

Alias-сегменты

me

R-ALIAS-1: вместо явного userId.

GET /users/{id}        ← общий, admin может смотреть любого
GET /users/me          ← тот же endpoint, но «свой профиль» через alias

Граничный тест: может ли супер-админ обратиться по другому ID к этому же endpoint?

  • Даme имеет смысл (admin делает GET /users/42, обычный user — GET /users/me).
  • Нет → endpoint singleton, me избыточен.

me — де-факто стандарт: GitHub API, Google API, Spotify API, Microsoft Graph. Альтернативы (self, current-user) допустимы, но менее распространены.

Временные и порядковые alias

R-ALIAS-2: для singleton-выборки.

GET /deployments/latest
GET /subscriptions/current
GET /invoices/next
GET /billing-periods/previous
GET /versions/first
GET /transactions/last

Это shortcut: вместо GET /deployments?orderBy=createdAt&order=desc&limit=1GET /deployments/latest.

Логические alias

R-ALIAS-3: по бизнес-признаку.

GET /payment-methods/default
GET /addresses/primary
GET /plans/active
GET /documents/draft

Singleton per user: «который из моих payment-methods default» — это один объект, не filter.

Запреты для me

R-ALIAS-X1: me где не нужен.

GET /users/me/orders        ✗ — orders уже из контекста токена
GET /orders                 ✓ — заказы текущего пользователя

Тест: «может ли супер-админ обратиться по другому ID?» Нет → me не нужен. Endpoint singleton (/profile, /settings).

R-ALIAS-X2: me без users/:

GET /me                     ✗ — me — alias для users/{id}, не отдельный ресурс
GET /users/me               ✓

Action-эндпоинты

Доменные команды, меняющие state агрегата.

Формат

R-ACT-1..4:

POST /orders/{id}/confirm           ✓ ресурс + действие
POST /orders/{id}/cancel            ✓
POST /orders/{id}/ship              ✓
POST /orders/{id}/refund            ✓

С body:

POST /orders/{id}/ship
Content-Type: application/json

{
  "trackingNumber": "TR-123456",
  "carrier": "DHL"
}
  • Имя — глагол в инфинитиве (confirm, не confirmation, не confirmed).
  • МетодPOST всегда, даже если операция идемпотентна по факту.
  • Параметры — в теле; если параметров нет — пустое тело допустимо.

Почему POST даже когда идемпотентно:

  • confirm — это команда, не замена ресурса (как PUT).
  • Семантически клиент инициирует действие, не describes target state.
  • HTTP cache не должен трогать POST.

Запреты

R-ACT-X1: existential или partial.

/orders/{id}/confirmation       ✗ — существительное
/orders/{id}/confirmed          ✗ — причастие
/orders/{id}/confirm            ✓ — глагол

R-ACT-X2: не-POST.

PUT /orders/{id}/confirm        ✗ — PUT = замена ресурса
POST /orders/{id}/confirm       ✓

Когда action vs PATCH

Часто возникает вопрос: «обновить статус заказа на CONFIRMED — это PATCH /orders/{id} { status: CONFIRMED } или POST /orders/{id}/confirm

СитуацияЧто выбрать
Меняем поле, нет бизнес-правилPATCH
Команда с side-effects (события, transitions)Action
Доменное имя есть (confirm, ship, refund)Action
Меняем name, description, emailPATCH
Меняем status (state machine)Action
Inline-команды (admin tool)Action для каждой, не общий PATCH

Action-эндпоинты делают семантику явной:

  • В access-логах видно: POST /orders/{id}/confirm vs PATCH /orders/{id} — что именно произошло.
  • Тесты на ABAC проще: canConfirmOrder(...) — конкретная permission.
  • Audit log: точное действие (cancel, refund), не abstract «order updated».

Что запрещено

АнтипаттернПравилоЧто взамен
me где endpoint singletonR-ALIAS-X1без me (singleton сам)
/api/v1/me без users/R-ALIAS-X2/api/v1/users/me
/orders/{id}/confirmationR-ACT-X1/orders/{id}/confirm
/orders/{id}/confirmedR-ACT-X1/orders/{id}/confirm
PUT /orders/{id}/confirmR-ACT-X2POST
PATCH /orders/{id} { status: CANCELLED } для командыR-ACT-1POST /orders/{id}/cancel
me для /api/v1/users/me/profile (двойной alias)R-ALIAS-X1/users/me/profile ОК; me/profile — нет
Многословный action cancelTheOrderImmediatelyR-ACT-2cancel

Куда дальше

  • REST API → Alias и Action (нормативно) — формулировки.
  • URL и ресурсы — формат пути, ресурсы.
  • Версионирование — action в v2.
  • Auth → ABAC — permission per action.
  • Audit admin-команд — action → audit log запись.
  • DDD → команды — domain commands соответствуют action-эндпоинтам.