本文へ移動
cccskills
無料GitHub で公開

api-design

Design and review intuitive, scalable, maintainable HTTP APIs. Use this skill whenever the user wants to design a new REST API, review an existing API or spec, write OpenAPI 3.x definitions, or work with HTTP semantics (GET/POST/PUT/PATCH/DELETE), status codes, idempotency (Idempotency-Key), error envelopes (RFC 7807 problem+json), pagination, filtering, versioning, or API auth (API keys, OAuth2 client credentials, rate limits). Also trigger for "API design", "RESTful", "endpoints", "OpenAPI", "Swagger", "ReDoc", "contract testing", or GraphQL and gRPC design questions.

インストール方法を見る

含まれるファイル(9)

  • SKILL.md18.0 KB
  • eval.yaml1.5 KB
  • graders/check.py21.3 KB
  • instructions/orders-api-openapi.md3.4 KB
  • references/error-handling.md7.7 KB
  • references/pagination-filtering.md5.8 KB
  • references/versioning-evolution.md5.7 KB
  • rubrics/quality.md2.1 KB
  • solutions/reference-orders-api-openapi8.6 KB

SKILL.md(原文)

インストールする前に、エージェントに与えられる指示の中身を確認できます。

API Design

HTTP APIs are the contract between your service and every client that consumes it. A well-designed API is consistent and predictable: the URL says which resource you are touching, the HTTP method says what happens to it, and the status code plus body say whether it worked and why not. This skill covers designing and reviewing such APIs — resource modeling, HTTP semantics, status codes, error envelopes, pagination, versioning, spec-first OpenAPI 3.x, and authentication basics — REST first, with GraphQL and gRPC covered in passing.

Quick Reference

TaskReference
Error envelopes, RFC 7807, idempotency keys, retry policyerror-handling.md
Cursor vs offset pagination, filtering, sorting, field selectionpagination-filtering.md
Versioning strategies, backward compatibility, deprecationversioning-evolution.md

Core Workflow

Design an endpoint set in five steps:

  1. Model resources and map HTTP semantics — identify the nouns (users, orders, products) and their relationships; name them as plural collections; one method per operation: read → GET, create → POST, full replace → PUT, partial update → PATCH, delete → DELETE, domain action → POST to an action sub-resource.
  2. Design the responses — success shapes, the error envelope (problem+json), and the exact status code per failure mode.
  3. Paginate and filter collections — choose cursor or offset, set defaults, define filter/sort/field-selection syntax.
  4. Write the OpenAPI spec first — the spec is the contract; generate docs and clients from it.
  5. Lock down auth and limits — authentication scheme, least-privilege scopes, rate limits with standard headers.

Resource Modeling

Nouns, not verbs

Resources are nouns; HTTP methods are the verbs. URLs must never contain verbs.

Anti-patternGood
GET /getUser?id=1GET /users/{id}
POST /createOrderPOST /orders
POST /deleteOrder?id=1DELETE /orders/{id}

Collections, sub-resources, actions

PatternExampleMeaning
CollectionGET /orderslist (paginated)
Sub-resourceGET /users/{id}/ordersorders owned by that user
ActionPOST /orders/{id}/canceldomain action with side effects

Relationships

  • Use sub-resources only for genuinely nested, exclusive ownership (/users/{id}/orders makes sense; /orders/{id}/customer does not — the customer is not owned by the order).
  • For non-ownership links, keep the related resource at top level: GET /orders?customer_id=.... Keep nesting shallow — never deeper than one level; embed related IDs in payloads, not whole objects.

Actions are POSTs

When a client operation is not CRUD — cancel, refund, publish, archive — model it as a POST to a named action sub-resource (POST /orders/{id}/cancel). POST is the only method with no idempotency guarantee, which fits side-effecting actions — but pair it with an Idempotency-Key (below).

HTTP Semantics

MethodSemanticsSafeIdempotentNotes
GETread a collection or instance✅✅never changes state; cacheable
POSTcreate a resource, or trigger an action❌❌returns 201 Created + Location
PUTfull replacement of an existing resource❌✅client sends the entire representation
PATCHpartial update (changed fields only)❌❌ by specsend only what changes
DELETEremove a resource❌✅repeat DELETE → 204 or 404, both fine

Safe = no side effects (safe to retry, cache, prefetch). Idempotent = N identical requests produce the same result as one.

Idempotency (PUT vs POST, Idempotency-Key)

  • PUT is inherently idempotent — use it when the client can supply the full representation. Same payload twice → same state.
  • POST and PATCH are not idempotent. A retried POST /orders creates two orders. Fix this with the Idempotency-Key request header: the client sends a UUID, the server stores key → response, and replays the stored response instead of re-executing.
POST /orders
Idempotency-Key: 9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d

{ "items": [ { "sku": "SKU-42", "qty": 2 } ] }
  • Require Idempotency-Key on any POST/PATCH that creates or mutates (payments, orders, subscriptions).
  • A replay with the same key but a different body → 409 Conflict.
  • Expire keys after a bounded window (Stripe uses 24h); document the window.
  • On replay, return the original stored response — that is what makes client retries safe.

Status Codes

Pick the narrowest correct code; do not invent meanings. Full 2xx–5xx table (304, 405, 502, 504 and friends): error-handling.md.

CodeUseExample
200 OKsuccessful read, update, or actionGET /orders/{id}
201 Createdresource created (set Location)POST /orders
400 Bad Requestmalformed syntax or missing required fieldinvalid JSON, unknown enum value
401 Unauthorizedmissing or invalid credentialsno/expired token
403 Forbiddenauthenticated but not allowedvalid token, wrong scope
404 Not Foundno such resource or routeGET /orders/9999
409 Conflictstate conflict; request cannot applyduplicate Idempotency-Key body
422 Unprocessable Entitywell-formed but semantically invalidorder with 0 items, negative price
429 Too Many Requestsrate limited (send Retry-After)burst over limit
500 Internal Server Errorunhandled server failurebug, DB outage
503 Service Unavailabledown / overloaded (send Retry-After)maintenance

Common mistakes

  • 200 with an error body — breaks every client's status-code handling. Errors live in 4xx/5xx.
  • 500 for client errors — validation failures are 4xx; 500 triggers alerts and pointless retries for something the client did.
  • 401 vs 403 — 401: who are you (no/expired credentials); 403: you are not allowed (authenticated, lacking permission or scope).

Error Responses

Use a consistent envelope everywhere, preferably RFC 7807 application/problem+json:

{
  "type": "https://api.example.com/problems/out-of-stock",
  "title": "Order cannot be placed",
  "status": 422,
  "detail": "SKU-42 has only 3 units in stock",
  "code": "OUT_OF_STOCK",
  "retryable": false,
  "errors": [{ "field": "items[0].qty", "code": "OUT_OF_STOCK", "message": "Only 3 units available" }]
}
  • type — stable machine-readable problem URI; title — short human summary; status — HTTP status; detail — human explanation; instance — URI of the request/resource.
  • Add a code field: a stable, documented string clients can branch on (OUT_OF_STOCK, INVALID_ARGUMENT, RATE_LIMITED). Never branch on the human-readable title/detail.
  • Add retryable (or derive it): 5xx and 429 are retryable; 4xx are not (except 408/425/429).
  • Field-level validation failures → an errors[] array with field, code, message.
  • Serve as Content-Type: application/problem+json; document every code in your API reference.

Pagination, Filtering, Sorting

Cursor vs offset

AspectOffset (?page=2&page_size=50)Cursor (?cursor=...)
Stabilitydrifts when rows are inserted/deleted mid-pagingstable — pages are anchored
UXsupports jump-to-page Nnext/prev only (no jump)
ImplementationOFFSET/LIMIT (trivial)keyset: WHERE (id > :cursor) LIMIT n
Best foradmin tables, small datasetslive, high-churn feeds
Orderinganyrequires a stable sort key

Default to cursor for public/live collections, offset for internal/admin. Set a default page size (25–50) and a hard max (100–1000); clamp or return 400 on overflow — and document it.

{ "data": [{ "id": "ord_8f2", "total": "129.00" }],
  "pagination": { "next_cursor": "eyJpZCI6Im9yZF84ZjIifQ", "has_more": true } }

Filtering, sorting, field selection

ConcernConventionExample
Exact match?key=value on known fields?status=shipped
Ranges*_gte / *_lte suffix (or [gte])?created_at_gte=2024-01-01
Sortingsort param; - prefix = descending?sort=-created_at,sku
Field selectionsparse fieldsets?fields=id,name,price

Validate every filter and sort field against a whitelist — unknown keys → 400, never silently ignored.

Versioning

StrategyExampleProsCons
URL path/api/v2/ordersvisible, cacheable per version, easy routingmultiple code paths over time
Media typeAccept: application/vnd.api+json; version=2clean URLshidden from casual inspection, harder to debug
Query param/orders?v=2trivial to addpollutes cache keys and logs; widely discouraged

URL path is the default for public APIs. Never version with query parameters for a public API.

Backward compatibility

Additive (safe, no version bump)Breaking (requires a new version)
new optional fields or query parametersremove or rename a field
new endpoint; widen enums; relax validationchange a field's type or meaning; make an optional field required

Evolve additively as long as you can; version only when a breaking change is unavoidable. When deprecating: announce it, keep the old version alive on a documented sunset schedule, and emit Deprecation / Sunset (RFC 8594) response headers.

Spec-First with OpenAPI 3.x

  1. Write the OpenAPI spec before the implementation — it is the single source of truth for shape, examples, and behavior.
  2. Lint it in CI — Spectral rules catch missing responses, undocumented status codes, and naming drift.
  3. Generate docs and clients from the spec — ReDoc / Redocly, Swagger UI, openapi-generator, openapi-typescript, orval.
  4. Contract-test it and treat spec and implementation as one — Schemathesis fuzzes the spec against the running service; Pact handles consumer-driven contracts; when a review finds a mismatch, fix the spec first, then the code.

Authentication & Rate Limiting

Schemes

SchemeUse forHowNotes
API keysimple machine clients, first-party toolsAuthorization: Bearer <key> or X-API-Key: <key>long-lived; treat as a secret; support rotation
OAuth2 client credentialsmachine-to-machinePOST /oauth/token (grant_type=client_credentials&scope=read:orders) → access tokenshort-lived tokens
OAuth2 authorization codeuser-facing apps acting for a userbrowser flow → access tokendelegate to an IdP (Auth0, Clerk, …)

Use scopes for least privilege: read:orders, write:orders, admin. A token with only read:orders calling a write endpoint → 403.

Rate limiting

On exceeding the limit, return 429 with Retry-After (seconds) plus the standard headers: X-RateLimit-Limit (window quota), X-RateLimit-Remaining, X-RateLimit-Reset (epoch seconds when the window resets). Document your window ("100 requests/minute per API key") and whether limits are per-key, per-IP, or per-user.

Worked Example: Orders API

An orders resource with a lifecycle — the endpoint set, and why each choice:

MethodPathSemantics
GET/orderslist, cursor-paginated, filterable by status, sortable by created_at
POST/orderscreate; requires Idempotency-Key; returns 201 + Location
GET/orders/{id}fetch one; 404 if unknown
PATCH/orders/{id}partial update (e.g. shipping address)
POST/orders/{id}/canceldomain action (triggers refunds); idempotency-keyed; 409 if already shipped
GET/orders/{id}/itemssub-resource — items belong exclusively to the order

Notes: no DELETE /orders — physical deletion is not part of the lifecycle; cancellation is a named action. No PUT — partial updates fit PATCH. Errors use the RFC 7807 envelope; collections use cursor pagination.

OpenAPI 3.1 excerpt (paths, security, components — trimmed):

openapi: 3.1.0
info: { title: Orders API, version: 2.0.0 }
servers: [{ url: https://api.example.com/v2 }]
security: [{ oauth2: [read:orders, write:orders] }]
paths:
  /orders:
    get:
      summary: List orders
      parameters:
        - { name: status, in: query, schema: { type: string, enum: [created, confirmed, shipped, cancelled] } }
        - { name: cursor, in: query, schema: { type: string, description: "Opaque pagination token" } }
        - { name: limit, in: query, schema: { type: integer, maximum: 100, default: 25 } }
      responses:
        "200": { description: A page of orders, content: { application/json: { schema: { $ref: "#/components/schemas/OrderPage" } } } }
        "429": { description: Too many requests, headers: { Retry-After: { schema: { type: integer } } }, content: { application/problem+json: { schema: { $ref: "#/components/schemas/Problem" } } } }
    post:
      summary: Create an order
      parameters:
        - { name: Idempotency-Key, in: header, required: true, schema: { type: string, format: uuid } }
      requestBody: { required: true, content: { application/json: { schema: { $ref: "#/components/schemas/NewOrder" } } } }
      responses:
        "201": { description: Order created, headers: { Location: { schema: { type: string } } }, content: { application/json: { schema: { $ref: "#/components/schemas/Order" } } } }
        "422": { description: Unprocessable entity, content: { application/problem+json: { schema: { $ref: "#/components/schemas/Problem" } } } }
components:
  securitySchemes:
    oauth2: { type: oauth2, flows: { clientCredentials: { tokenUrl: https://auth.example.com/oauth/token, scopes: { read:orders: Read orders, write:orders: Create and update orders } } } }
  schemas:
    Problem: { type: object, required: [type, title, status, code], properties: { type: { type: string, format: uri }, title: { type: string }, status: { type: integer }, detail: { type: string }, instance: { type: string }, code: { type: string }, retryable: { type: boolean } } }
    Order: { type: object, required: [id, status, total, currency], properties: { id: { type: string, example: ord_8f2 }, status: { type: string, enum: [created, confirmed, shipped, cancelled] }, total: { type: string, example: "129.00" }, currency: { type: string, example: USD } } }
    NewOrder: { type: object, required: [items], properties: { items: { type: array, minItems: 1, items: { type: object, required: [sku, qty], properties: { sku: { type: string }, qty: { type: integer, minimum: 1 } } } } } }
    OrderPage: { type: object, required: [data, pagination], properties: { data: { type: array, items: { $ref: "#/components/schemas/Order" } }, pagination: { type: object, required: [has_more], properties: { next_cursor: { type: string }, has_more: { type: boolean } } } } }

Pre-Review Checklist

Run this on any existing API before approving changes or declaring it done:

#AreaCheck
1Naming & URLsPlural nouns, consistent casing, no verbs in URLs
2Methods & idempotencyGET never mutates; PUT full replace, PATCH partial; creating/mutating POST/PATCH accept Idempotency-Key
3Status codesNo 200-with-error-body; 4xx for client errors; narrowest correct code
4ErrorsOne envelope everywhere (RFC 7807); stable machine-readable codes documented
5PaginationCursor or offset chosen and documented; default + max page size; has_more / next token
6Filtering/sortingParams whitelisted and validated; unknown keys → 400
7VersioningStrategy documented; no silent breaking changes; deprecation has a sunset plan
8Spec fidelityOpenAPI exists, linted, matches behavior (contract tests in CI)
9Auth & rate limitsLeast-privilege scopes; X-RateLimit-* headers; Retry-After on 429
10SecurityTLS everywhere; no secrets in URLs/logs; no stack traces in responses

Anti-Patterns to Avoid

  • Verbs in URLs (/getUser, /createOrder) — the method is the verb.
  • 200 with an error body — clients branch on status codes; you have just broken all of them.
  • 500 for client mistakes — mis-validated input is a 4xx; 500 means a server bug.
  • Deep nesting (/users/{id}/orders/{oid}/items/{iid}) — flat resources + query params scale better.
  • Bare POST without idempotency on creates and money-adjacent operations — double-submits are real.
  • Unbounded collections — every list endpoint paginates or dies.

When to Use / Not Use

Use this skill when:

  • Designing a new REST API, or a new set of endpoints for an existing service
  • Reviewing an API design doc, an OpenAPI spec, or a PR that changes endpoint behavior
  • Establishing API design standards for a team or platform

Do not use when:

  • The "API" is a library or function interface (Python SDK internals, method signatures) — different concerns
  • Designing event payloads or message-broker contracts (Kafka, SQS) — no status codes or idempotency keys in the same sense
  • The user wants a deep GraphQL- or gRPC-only treatment — this skill covers them in passing only; use dedicated GraphQL/gRPC guides

レビュー

まだレビューはありません。使ってみた感想をお寄せください。

同じリポジトリのスキル

概要と使いどころ

Adaption AI SDK for synthetic data augmentation and dataset adaptation. Use when building data pipelines with the Adaption Python SDK, uploading datasets (local files, Hugging Face, Kaggle), running augmentation/adaptation jobs, configuring brand controls (hallucination mitigation, safety categories, length), recipe specifications (reasoning traces, deduplication, preference pairs, prompt rephrase), evaluating dataset quality, downloading results, or any workflow involving `pip install adaption`, `from adaption import Adaption`, Adaptive Data, or the adaptionlabs.ai API. Also trigger when the user mentions synthetic data generation for fine-tuning, dataset augmentation pipelines, DPO preference pair generation, or grounding-based hallucination reduction on training data.

日本語の概要は準備中です。原文の説明を表示しています。

svngoku/coding-agents-skills122026年8月14日 更新

Design relational database schemas (and choose when to go NoSQL) that stay maintainable and fast. Use this skill whenever the user mentions tables, DDL, entities and relationships, normalization (1NF/2NF/3NF), primary and foreign keys, UUID vs bigint IDs, indexes (B-tree, composite, covering, partial), EXPLAIN, constraints (CHECK, UNIQUE, exclusion), transactions and isolation levels, migrations (Alembic, Prisma, Flyway, expand-contract, backfilling), or SQL vs NoSQL (MongoDB, DynamoDB, Cassandra, graph databases). Also trigger for "design the database", "model this domain", "which database should I use", or writing ORM models and migration files for PostgreSQL, MySQL, SQLite, or SQL Server.

日本語の概要は準備中です。原文の説明を表示しています。

svngoku/coding-agents-skills122026年8月14日 更新

ddd

無料

Domain-Driven Design system for software development. Use when designing new systems with DDD principles, refactoring existing codebases toward DDD, generating code scaffolding (entities, aggregates, repositories, domain events), facilitating Event Storming sessions, creating bounded context maps, or performing code reviews with a DDD lens. Covers both strategic design (bounded contexts, subdomains, context maps, ubiquitous language) and tactical design (entities, value objects, aggregates, domain services, repositories). Supports all major architecture patterns (Hexagonal/Ports & Adapters, CQRS, Event Sourcing, Clean Architecture) with language-agnostic guidance and concrete examples in Python and TypeScript.

日本語の概要は準備中です。原文の説明を表示しています。

svngoku/coding-agents-skills122026年8月14日 更新

genai-tk

無料

Build GenAI and agentic applications with the genai-tk toolkit (https://github.com/tclatos/genai-tk) — a YAML-driven wrapper over LangChain, LangGraph, and 100+ LLM providers. Use this skill whenever the user mentions genai-tk, genai_tk, the GenAI Toolkit, `cli init`, `LangchainAgent`, `get_llm`/`get_embeddings`, `RetrieverFactory`/`ManagedRetriever`, the four bundled agent frameworks (ReAct, Deep, Deer-flow, SmolAgents), the OpenSandbox Docker integration, the `model_id@provider` identifier format, the `global_config()`/`OmegaConfig` system with `app_conf.yaml` and `:merge`, BAML structured extraction, SkillsMiddleware, writing or editing the toolkit's YAML profiles (langchain.yaml, deerflow.yaml, llm.yaml, retrievers.yaml), composing retrievers (vector/bm25/ensemble/reranked/pg_hybrid/zero_entropy), or extending the CLI with `CliTopCommand`. Trigger even when the user only says "the toolkit" in context.

日本語の概要は準備中です。原文の説明を表示しています。

svngoku/coding-agents-skills122026年8月14日 更新

langchain

無料

Build AI agents with LangChain framework. Use when building agents, tools, memory, MCP integrations, RAG pipelines, multi-agent systems, or any LLM-powered applications using LangChain or LangGraph in Python or TypeScript.

日本語の概要は準備中です。原文の説明を表示しています。

svngoku/coding-agents-skills122026年8月14日 更新

Decompose systems into microservices and apply canonical distributed-systems patterns. Use this skill whenever the user wants to split a monolith into services, design service boundaries, choose between microservices and a modular monolith, implement sagas or the outbox pattern, set up CQRS or event sourcing, configure an API gateway or BFF, add resilience (circuit breakers, retries, timeouts), or implement distributed tracing with OpenTelemetry. Also trigger for distributed transactions, service discovery, event-driven architecture, contract testing with Pact, canary releases, and idempotent consumers.

日本語の概要は準備中です。原文の説明を表示しています。

svngoku/coding-agents-skills122026年8月14日 更新

svngoku のスキルをすべて見る

このスキルの問題を報告する