원클릭으로
rest-api-design
Use when designing, reviewing, or documenting HTTP REST API endpoints, resources, contracts, or schemas.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
메뉴
Use when designing, reviewing, or documenting HTTP REST API endpoints, resources, contracts, or schemas.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
SOC 직업 분류 기준
Use when implementing background jobs, task queues, scheduled jobs, retries, or any Redis-backed async worker in a Python backend service in this harness. arq is the chosen queue (async-native, Redis-backed). Replaces the old bullmq skill.
Use when creating a new branch, starting new feature work, fixing a bug on a new branch, or any situation where a branch needs to be created. Use when the user asks to "create a branch", "start a new branch", "branch off of X", or "make a branch for this work".
Use when creating CI/CD pipelines for any project. Use when asked to "set up CI/CD", "create a pipeline", "automate deployments", "configure GitHub Actions", "set up Vercel/Render/AWS", or similar. The harness is a polyglot monorepo — a Python (FastAPI + uv) backend in `apps/api/` and a TypeScript (Vite + pnpm) frontend in `apps/web/`. Pipelines run the two stacks as parallel lanes that join at a final gate.
Use when writing, reviewing, or editing a Dockerfile or docker-compose file. Use when asked to "containerize", "dockerize", "add Docker support", or "write a Dockerfile" for any application or service in this harness — FastAPI backend (Python + uv) or Vite frontend (TypeScript + pnpm, served as static assets).
Use when writing, reviewing, or refactoring TypeScript code on the frontend — especially when tempted to use `any`, type assertions, unvalidated casts, or when designing types, generics, utility types, or tsconfig settings. Backend code in this harness is Python, not TypeScript; see `effective-python` / `python-linting` for the backend equivalents.
FastAPI implementation guide. Load whenever building or modifying any backend HTTP service in this harness — defining routes, request/response models, dependencies, middleware, error handlers, lifespan events, or background tasks. Triggers include: APIRouter, Depends, FastAPI app instance, response_model, OpenAPI generation, async endpoint handlers. Use alongside `sqlalchemy`, `pydantic`, and `rest-api-design`.
| name | rest-api-design |
| description | Use when designing, reviewing, or documenting HTTP REST API endpoints, resources, contracts, or schemas. |
/users, /orders. Never /createUser or /getOrders./users, not /user./pending-orders, not /pendingOrders or /PendingOrders.| Method | Use Case | Idempotent? | Safe? |
|---|---|---|---|
GET | Read resources | Yes | Yes |
POST | Create new resource | No | No |
PUT | Replace complete resource | Yes | No |
PATCH | Partial update | No | No |
DELETE | Remove resource | Yes | No |
POST /projects/{id}/tasksGET /tasks/{taskId}/orgs/{id}/repos/{id}/issues is the limit.For operations that don't fit CRUD (e.g., "publish", "ban", "archive"):
PATCH /articles/{id} with { "status": "published" }PUT /articles/{id}/publicationPOST /articles/{id}/actions/publish (last resort)GET /user-profilesPOST /projects (not POST /createProject)GET /users (except singletons like /me)q: Search query stringlimit: Max results per pageoffset: Starting index (0-based)page: Page number (1-based)fields: Comma-separated list of fields to includeembed: Comma-separated list of related resources to includesortBy: Sort field namesnake_case field names in JSON (created_at, user_id). That is the FastAPI + Pydantic default and it matches the SQLAlchemy model field names, which keeps the serialisation layer thin.openapi-typescript — there is no camelCase translation layer. See the openapi-codegen skill.alias_generator=to_camel to "translate" at the API edge. It creates two names for the same field (DB vs wire) and the cost compounds.GET /v1/usersAccept: application/vnd.myapi.v1+json{
"data": [ ...items... ],
"meta": {
"pagination": {
"total": 100,
"count": 20,
"perPage": 20,
"currentPage": 2,
"totalPages": 5,
"links": {
"next": "https://api.example.com/v1/users?page=3",
"prev": "https://api.example.com/v1/users?page=1"
}
}
}
}
Always wrap collections in a data key. Never return naked arrays.
ISO 8601 UTC: "createdAt": "2023-10-27T14:30:00.000Z". Always UTC (Z suffix). Never epoch seconds.
String-based IDs (UUIDs or prefixed IDs like usr_123abc) to prevent enumeration. Avoid sequential integers for public interfaces.
{
"type": "about:blank",
"title": "Invalid Request",
"status": 400,
"detail": "Email is required.",
"instance": "/v1/users",
"errors": [
{ "field": "email", "message": "Must be a valid email address" }
]
}
Success (2xx): 200 OK, 201 Created (with Location header), 202 Accepted (async), 204 No Content (deletion/update with no body).
Client Error (4xx): 400 Bad Request, 401 Unauthorized, 403 Forbidden, 404 Not Found, 405 Method Not Allowed, 409 Conflict, 422 Unprocessable Entity, 429 Too Many Requests.
Server Error (5xx): 500 Internal Server Error, 503 Service Unavailable.
The universal rules above describe what to ship. FastAPI is how to ship it in this harness. The fastapi, pydantic, and openapi-codegen skills cover the details; the load-bearing rules that affect API design are:
response_model= is mandatory on every route. It populates /openapi.json, strips fields that aren't in the schema, and is the contract the frontend regenerates its types from. A route without response_model ships unknown to the frontend.status_code= is explicit. Default is 200 — set 201 for create, 204 for delete-with-no-body, 202 for async-accepted.operation_id= is stable. The generated frontend client method names are derived from this; a refactor that renames the handler function silently changes the client's method names unless operation_id is pinned.tags=[...] on the router — groups the OpenAPI spec by resource.responses={401: {...}, 404: {...}, ...} — document every non-success status code the frontend needs to handle. Undocumented codes are a contract bug.HTTPException(status_code=..., detail="...") for the happy-path cases. For RFC 7807 conformance with field-level errors, use a shared ErrorResponse Pydantic model and register an exception handler that returns it.tenant_id, user_id, or role from the request body — only from dependencies (get_current_user, get_tenant_db). See the multi-tenancy skill.200 OK for errors → use 4xx/5xxPOST for updates → use PATCH/PUTresponse_model= → the OpenAPI spec has no success-response schema, and the generated frontend client gets unknown everywhereoperation_id= → frontend client method names depend on FastAPI's defaults and silently change when you rename a handleralias_generator=to_camel on the response schema → creates two names for the same field; pick snake_case and stick with it