agentsclimarketplace

Api design

Skill Vitammiin/agent-vorcl-flow/skills/api-design

Проектирование HTTP API — REST-конвенции (ресурсы, методы, статус-коды), пагинация (cursor vs offset), версионирование, идемпотентность (Idempotency-Key), формат ошибок RFC 7807 (problem+json), безопасность и rate limiting. Use при проектировании, ревью или версионировании API и эндпоинтов, выборе кодов ошибок, пагинации, лимитов или формата ответа.From its SKILL.md

Install
npx -y skills add Vitammiin/agent-vorcl-flow --skill api-design

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 2 stars2 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

SKILL.md

7.3 KB, as published. Nobody here has run it

Навык: API Design

REST-конвенции

Ресурсы — существительные во множественном числе; действие выражает HTTP-метод, не URL (POST /orders, а не POST /createOrder). Вложенность — максимум один уровень (/users/{id}/orders), глубже — фильтром (/orders?userId=). Действие вне CRUD — суб-ресурсом: POST /orders/{id}/cancel.

МетодСемантикаИдемпотентенУспехТипичные ошибки
GETчтение✅200404
POSTсоздание / действие❌201 (+ Location) или 200400, 409, 422
PUTполная замена✅200404, 409
PATCHчастичное обновление❌200404, 409, 422
DELETEудаление✅204404

Статусы ошибок: 400 — синтаксически кривой запрос; 422 — валидный JSON, не прошедший бизнес-валидацию; 401 — не аутентифицирован; 403 — аутентифицирован, но нельзя; 409 — конфликт состояния (дубликат, устаревшая версия); 429 — превышен лимит (+ Retry-After).

Пагинация

Offset (?page=3&limit=20)Cursor (?cursor=xyz&limit=20)
Простота✅ проще, произвольная страницасложнее, только «дальше»
Стабильность при вставках/удалениях❌ дубли и пропуски между страницами✅ стабильна
Скорость на глубине❌ OFFSET 100000 читает и выбрасывает✅ WHERE (sort_key, id) < cursor по индексу
Когдаадминки, маленькие статичные спискиленты, публичные API, большие/живые данные

Cursor — непрозрачная строка (base64 от (sort_key, id)), клиент её не парсит. Ответ списка — конверт: { "data": […], "nextCursor": "…", "hasMore": true }. Лимит — с дефолтом и максимумом (например 20/100).

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

  • Ломающее (удаление/переименование поля, смена типа или семантики) — только в новой версии. Добавление опциональных полей — не ломающее, версии не требует.
  • Дефолт — версия в пути: /v1/… (явно, кэшируемо, просто в роутинге). Альтернатива — заголовок (Accept: …;version=2) для чистых URL.
  • Клиент — tolerant reader: неизвестные поля ответа игнорирует, тогда добавления безопасны.
  • Старую версию не бросай молча: Deprecation/Sunset-заголовки, срок жизни, заметки по миграции.

Идемпотентность

  • GET/PUT/DELETE идемпотентны по контракту — клиент может безопасно ретраить.
  • POST с побочным эффектом (платёж, заказ) — Idempotency-Key: клиент шлёт уникальный ключ заголовком; сервер хранит key → результат (Redis/БД, TTL ~24ч) и на повтор возвращает сохранённый ответ, не выполняя операцию дважды. Обязателен для денежных операций и любых ретраящихся вызовов (вебхуки, очереди).
  • Потребители очередей — идемпотентны всегда: at-least-once означает, что дубли будут.

Ошибки: RFC 7807 (application/problem+json)

Единый формат всех ошибок API:

{
  "type": "https://api.example.com/errors/insufficient-funds",
  "title": "Insufficient funds",
  "status": 422,
  "detail": "Balance 5.00 is less than order total 20.00",
  "instance": "/orders/req-7f3a",
  "code": "INSUFFICIENT_FUNDS",
  "errors": [{ "field": "amount", "message": "…" }]
}
  • code — стабильный машинный код: по нему ветвится клиент; человекочитаемый текст может меняться и локализоваться.
  • Валидационные ошибки — списком по полям, все сразу, не по одной.
  • Не течь внутренностями: stack trace, SQL, имена таблиц — только в логи; наружу — generic 500 + instance/requestId для соотнесения с логами.

Пример хорошего эндпоинта

POST /v1/orders
Authorization: Bearer <token>
Idempotency-Key: 3f2a-…
{ "items": [{ "productId": "p_1", "qty": 2 }] }

201 Created
Location: /v1/orders/ord_9x1
{ "id": "ord_9x1", "status": "pending", "total": { "amount": 4200, "currency": "EUR" }, "createdAt": "2026-08-06T10:00:00Z" }

Деньги — минорными единицами + валюта (не float); даты — ISO 8601 в UTC; id — префиксованные строки. Ошибка того же эндпоинта — problem+json с 422 и машинным code.

Безопасность (минимум)

Аутентификация на каждом эндпоинте (Bearer/JWT), авторизация — на уровне ресурса (чужой orderId → 403/404), rate limiting per-user/per-key с 429, вход валидируется схемой (zod) до бизнес-логики.

Углублённо

  • REST vs GraphQL vs gRPC: GraphQL — клиенты с разными потребностями в данных; gRPC — внутренняя сервис-сервис связь с жёсткими контрактами; дефолт публичного API — REST.
  • Контракты и OpenAPI-покрытие → навык swagger-coverage.
  • Коды и обработка ошибок → навык error-handling.
  • Локализация ответов (i18n) → навык i18n: контракт ошибок — стабильный машинный code + параметры (не готовый переведённый текст), выбор языка по Accept-Language/локали пользователя.

Keep looking

Skills are one crate of 627,801. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.