20. OpenAPI-метаданные
20.1 Обязательно
-
R-OAS-1. Каждый эндпоинт имеет уникальный
operationIdвcamelCase. Паттерн:действие+ресурс./api/v1/orders: get: operationId: getOrders post: operationId: createOrder /api/v1/orders/{id}: get: operationId: getOrder put: operationId: updateOrder delete: operationId: deleteOrder /api/v1/orders/{id}/confirm: post: operationId: confirmOrder /api/v1/orders/search: post: operationId: searchOrders -
R-OAS-2. Группировка эндпоинтов через
tags. Один тег на ресурс, имя — множественное число с заглавной. Action-эндпоинты относятся к тегу родительского ресурса (confirm→Orders).tags: - name: Orders description: 'Управление заказами' - name: Users description: 'Управление пользователями' /api/v1/orders: get: tags: [Orders] post: tags: [Orders] /api/v1/orders/{id}/confirm: post: tags: [Orders] -
R-OAS-3. Параметры пути в OpenAPI именуются уникально по контексту:
{orderId},{itemId}. В дизайн-документации (см.R-NEST-4в URL и ресурсы) используется{id}— контекст устраняет неоднозначность; в OpenAPI это требование инструмента (Swagger/Redoc не работают с одинаковыми именами параметров)./api/v1/orders/{orderId}/items/{itemId}: get: parameters: - name: orderId in: path required: true schema: type: string format: uuid - name: itemId in: path required: true schema: type: string format: uuid -
R-OAS-4. Каждый эндпоинт имеет
summary(короткая фраза, до 80 символов).description— по необходимости, если логика неочевидна./api/v1/orders/{id}/confirm: post: summary: 'Подтвердить заказ' description: | Переводит заказ из статуса CREATED в CONFIRMED. Заказ должен содержать хотя бы одну позицию. После подтверждения изменение состава заказа невозможно.
21. Антипаттерны
Сводка ссылок на запрещающие правила (X-коды) — единая точка для быстрой проверки контракта.
| Антипаттерн | Правило | Корректно |
|---|---|---|
| Глагол в URL для CRUD | R-URL-X4 | POST /api/v1/orders |
| CamelCase в пути | R-URL-X1 | /order-items |
| snake_case в пути | R-URL-X1 | /order-items |
| Завершающий слеш | R-URL-X2 | /api/v1/orders |
| Расширение файла в пути | R-URL-X3 | /api/v1/orders |
| ID в теле вместо пути | R-NEST-X2 | PUT /orders/{id} |
| Глубокая вложенность | R-NEST-X1 | /comments?itemId={id} |
| Множественное/единственное число вперемешку | R-RES-X2 | /orders/{id}/items |
| GET с побочным эффектом | R-MTH-X1 | POST /orders/{id}/cancel |
| Версия в query | R-VER-X2 | /api/v1/orders |
| Минорная версия в пути | R-VER-X1 | /api/v1/... |
| Бизнес-логика в query | R-QRY-X4 | POST /orders/{id}/cancel |
| Comma-separated массивы в query | R-QRY-X3 | повтор параметра |
page=0 в публичном контракте | R-QRY-X2 | page=1 |
Префикс X- в заголовках | R-HDR-X1 | доменный префикс (Shop-) |
| Envelope-обёртка | R-RSP-X4 | плоский ресурс |
null в успешном ответе | R-RSP-X1 | отсутствие поля |
nullable: true в OpenAPI | R-RSP-X3 | required или отсутствие |
application/json для ошибок | R-ERR-X1 | application/problem+json |
type: "about:blank" в ошибках | R-ERR-X2 | URN urn:problem:<service>:<code> |
Stack traces в теле 500 | R-ERR-X4 | code + общий detail |
| Rate limiting без заголовков | R-RATE-X1 | Retry-After + RateLimit-* |
Deprecation без Sunset | R-DEP-X1 | заголовок Sunset с датой |
me для собственных ресурсов | R-ALIAS-X1 | контекст из токена |
| HATEOAS-ссылки в теле | R-PRIN-X1 | OpenAPI-описание навигации |
| Любой метод кроме POST для action | R-ACT-X2 | POST /orders/{id}/confirm |
Финальная сводка: правил «Обязательно» — около 75, «Запрещено» — около 35. На любое нарушение ревью цитирует конкретный код (R-URL-3, R-ERR-X2, R-MTH-X1), чтобы автор PR мог быстро найти контекст.