Опирается на правила: R-OAS-1..4 + сводка X-кодов из REST API Style Guide → раздел OpenAPI-метаданные и антипаттерны.

Важно знать

  • operationId — уникальный, camelCase, формат действие + ресурс (createOrder, confirmOrder).
  • tags — один на ресурс, множественное число с заглавной (Orders, Users).
  • Action-эндпоинты относятся к тегу родительского ресурса (confirmOrders).
  • Параметры пути в OpenAPI именуются уникально ({orderId}, {itemId}).
  • В дизайне URL{id} (контекст устраняет неоднозначность).
  • summary — короткая фраза до 80 символов. description — если логика неочевидна.
  • Сводка антипаттернов из всех разделов гайда — единая checkin-таблица.

OpenAPI — машиночитаемый контракт REST API. Хорошо оформленный OpenAPI генерирует client SDK, Swagger UI, Postman collections. UCP формулирует минимальные метаданные, без которых эти инструменты работают плохо.

operationId

R-OAS-1: уникальный, camelCase, действие + ресурс.

/api/v1/orders:
  get:
    operationId: getOrders
  post:
    operationId: createOrder

/api/v1/orders/{id}:
  get:
    operationId: getOrder
  put:
    operationId: updateOrder
  patch:
    operationId: patchOrder
  delete:
    operationId: deleteOrder

/api/v1/orders/{id}/confirm:
  post:
    operationId: confirmOrder

/api/v1/orders/search:
  post:
    operationId: searchOrders

Почему это критично:

  • Client SDK generators (openapi-generator) используют operationId как имя метода: orderService.confirmOrder(orderId).
  • Без operationId — генератор делает что-то странное (postOrdersOrderIdConfirm).
  • Уникальный — в client SDK не два метода с одним именем.
  • camelCase — стандарт для имён методов в большинстве языков (Java, JS, Python).

Конвенция:

  • get{Resource} — single (getOrder).
  • get{Resources} — list (getOrders).
  • create{Resource} — POST для создания.
  • update{Resource} — PUT для замены.
  • patch{Resource} — PATCH.
  • delete{Resource} — DELETE.
  • {verb}{Resource} — action (confirmOrder, cancelOrder).
  • search{Resources}POST /search (см. Query).

tags

R-OAS-2: один тег на ресурс.

tags:
  - name: Orders
    description: 'Управление заказами'
  - name: Users
    description: 'Управление пользователями'
  - name: Payments
    description: 'Платежи и refund'

/api/v1/orders:
  get:
    tags: [Orders]
  post:
    tags: [Orders]

/api/v1/orders/{id}/confirm:
  post:
    tags: [Orders]              # action к Orders

Тег:

  • Имя — множественное число с заглавной (Orders, Users).
  • description — короткое объяснение группы.
  • Action-эндпоинты относятся к тегу родительского ресурса. POST /orders/{id}/confirmOrders, не отдельный OrderActions.

В Swagger UI / Redoc — endpoints группируются по тегам. Без правильных тегов — flat-список 100+ эндпоинтов, невозможно ориентироваться.

Параметры пути в OpenAPI

R-OAS-3: уникальные имена.

/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

Двойной стандарт с дизайном URL (URL и ресурсы R-NEST-4):

  • В дизайне URL{id} (контекст ресурса устраняет неоднозначность).
  • В OpenAPI — уникальные ({orderId}, {itemId}).

Причина: Swagger UI и Redoc не работают с одинаковыми именами параметров в одном пути. Это требование инструмента, не семантика.

summary и description

R-OAS-4:

/api/v1/orders/{id}/confirm:
  post:
    operationId: confirmOrder
    tags: [Orders]
    summary: 'Подтвердить заказ'
    description: |
      Переводит заказ из статуса CREATED в CONFIRMED.
      Заказ должен содержать хотя бы одну позицию.
      После подтверждения изменение состава заказа невозможно.
  • summary — короткая фраза (до 80 символов). Отображается в Swagger UI рядом с endpoint.
  • description — Markdown, многострочный. Только если логика неочевидна; пустой description — лучше отсутствия.

Сводка антипаттернов

Единая таблица из всех разделов гайда. Используется как checklist на ревью.

URL

АнтипаттернПравилоКорректно
Глагол в URL для CRUDR-URL-X4POST /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-X2PUT /orders/{id}
Глубокая вложенностьR-NEST-X1/comments?itemId={id}
Mix единственного/множественногоR-RES-X2/orders/{id}/items
GET с побочным эффектомR-MTH-X1POST /orders/{id}/cancel

Версионирование

АнтипаттернПравилоКорректно
Версия в queryR-VER-X2/api/v1/orders
Минорная версияR-VER-X1/api/v1/...
Дата-версия /api/2026/R-VER-X1v1, v2
Endpoint без /apiR-VER-X3/api/v1/...
Новая версия для optional поляR-VER-X4в текущей

Query

АнтипаттернПравилоКорректно
Бизнес-логика в query (?action=cancel)R-QRY-X4POST /orders/{id}/cancel
Comma-separated массивыR-QRY-X3повтор параметра
page=0 в публичном контрактеR-QRY-X2page=1
snake_case в параметрахR-QRY-X1camelCase
Парсинг cursor на клиентеR-QRY-X5opaque token

JSON и ответы

АнтипаттернПравилоКорректно
Envelope { success, data }R-RSP-X4плоский ресурс
null в успешном ответеR-RSP-X1отсутствие поля
"" для отсутствияR-RSP-X2отсутствие поля
nullable: true в OpenAPIR-RSP-X3required или отсутствие

Заголовки

АнтипаттернПравилоКорректно
Префикс X- в кастомных headersR-HDR-X1доменный префикс (Shop-)

Ошибки

АнтипаттернПравилоКорректно
application/json для ошибокR-ERR-X1application/problem+json
type: "about:blank"R-ERR-X2URN urn:problem:<service>:<code>
HTTP-код вне списка (418, 422, 451)R-ERR-X3стандартные
Stack traces в 500R-ERR-X4code + общий detail

Rate limiting и deprecation

АнтипаттернПравилоКорректно
429 без headersR-RATE-X1Retry-After + RateLimit-*
Deprecation без SunsetR-DEP-X1заголовок с датой

Alias и actions

АнтипаттернПравилоКорректно
me для собственных ресурсовR-ALIAS-X1контекст из токена
me без users/ префиксаR-ALIAS-X2/users/me
HATEOAS-ссылки в телеR-PRIN-X1OpenAPI описывает навигацию
Существительное в action (/confirmation)R-ACT-X1/confirm
Любой метод кроме POST для actionR-ACT-X2POST /orders/{id}/confirm

Локализация

АнтипаттернПравилоКорректно
Локализация code enumR-LOC-X1английский
Локализация titleR-LOC-X1стандартное HTTP-название
Локализация JSON-полейR-LOC-X1английский

Куда дальше

  • REST API → OpenAPI и антипаттерны (нормативно) — формулировки.
  • URL и ресурсы — R-NEST-4 {id} vs {orderId}.
  • Alias и Action-эндпоинты — action operationId.
  • Версионирование — v1/v2 в OpenAPI.
  • Ошибки RFC 9457 — ProblemDetails схема.
  • Resilience → OpenAPI generator binding — client SDK generation.
  • Use Case Pattern — UseCase соответствует operationId.