REST API: OpenAPI-метаданные и антипаттерны
OpenAPI-метаданные: operationId, теги. Антипаттерны REST API.
REST API OpenAPI антипаттерны: 20. OpenAPI-метаданные
20.1. operationId
REST API OpenAPI антипаттерны — каждый эндпоинт должен иметь уникальный 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
Паттерн: действие + ресурс (getOrders, createOrder, confirmOrder).
20.2. Теги (tags)
Группировка эндпоинтов по ресурсу. Один тег на ресурс, имя -- множественное число с заглавной:
tags:
- name: Orders
description: 'Управление заказами'
- name: Users
description: 'Управление пользователями'
/api/v1/orders:
get:
tags: [Orders]
post:
tags: [Orders]
/api/v1/orders/{id}/confirm:
post:
tags: [Orders]
Action-эндпоинты относятся к тегу родительского ресурса (confirm -> Orders).
20.3. summary и description
summary-- короткая фраза (до 80 символов), отображается в списке эндпоинтовdescription-- подробное описание (markdown), отображается при раскрытии эндпоинта
/api/v1/orders/{id}/confirm:
post:
summary: 'Подтвердить заказ'
description: |
Переводит заказ из статуса CREATED в CONFIRMED.
Заказ должен содержать хотя бы одну позицию.
После подтверждения изменение состава заказа невозможно.
summary обязателен для каждого эндпоинта. description -- по необходимости, если логика неочевидна.
21. Антипаттерны
- Глагол в URL для CRUD --
POST /createOrder->POST /api/v1/orders - CamelCase в пути --
/orderItems->/order-items - snake_case в пути --
/order_items->/order-items - ID в теле вместо пути --
PUT /orders {"id":"..."}->PUT /orders/{id} - GET с побочным эффектом --
GET /orders/{id}/approve->POST /orders/{id}/approve - Глубокая вложенность --
/users/{id}/orders/{id}/items/{id}/comments->/comments?itemId={id} - Множественное/единственное число вперемешку --
/order/{id}/items->/orders/{id}/items - Версия в query --
/orders?version=1->/api/v1/orders - Бизнес-логика в query --
/orders?action=cancel->POST /orders/{id}/cancel - Раскрытие внутренней модели --
/db/tables/orders/rows->/api/v1/orders - Envelope-обёртка --
{ "success": true, "data": {...} }-> плоский объект ресурса (см. раздел 11.8) nullable: trueвместо optional -- не использоватьnullable, поле либо есть, либо отсутствует (см. раздел 11.7)- Rate limiting без заголовков --
429безRetry-AfterиRateLimit-*(см. раздел 14) - Deprecation без
Sunset--deprecated: trueв OpenAPI, но без заголовкаSunsetи даты отключения (см. раздел 16) application/jsonдля ошибок -- использоватьapplication/problem+jsonдля RFC 9457 (см. раздел 13)