Опирается на правила:
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=1 — GET /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, email | PATCH |
Меняем status (state machine) | Action |
| Inline-команды (admin tool) | Action для каждой, не общий PATCH |
Action-эндпоинты делают семантику явной:
- В access-логах видно:
POST /orders/{id}/confirmvsPATCH /orders/{id}— что именно произошло. - Тесты на ABAC проще:
canConfirmOrder(...)— конкретная permission. - Audit log: точное действие (
cancel,refund), не abstract «order updated».
Что запрещено
| Антипаттерн | Правило | Что взамен |
|---|---|---|
me где endpoint singleton | R-ALIAS-X1 | без me (singleton сам) |
/api/v1/me без users/ | R-ALIAS-X2 | /api/v1/users/me |
/orders/{id}/confirmation | R-ACT-X1 | /orders/{id}/confirm |
/orders/{id}/confirmed | R-ACT-X1 | /orders/{id}/confirm |
PUT /orders/{id}/confirm | R-ACT-X2 | POST |
PATCH /orders/{id} { status: CANCELLED } для команды | R-ACT-1 | POST /orders/{id}/cancel |
me для /api/v1/users/me/profile (двойной alias) | R-ALIAS-X1 | /users/me/profile ОК; me/profile — нет |
Многословный action cancelTheOrderImmediately | R-ACT-2 | cancel |
Куда дальше
- REST API → Alias и Action (нормативно) — формулировки.
- URL и ресурсы — формат пути, ресурсы.
- Версионирование — action в v2.
- Auth → ABAC — permission per action.
- Audit admin-команд — action → audit log запись.
- DDD → команды — domain commands соответствуют action-эндпоинтам.