一键导入
api-design
Use when designing REST or GraphQL APIs - covers OpenAPI spec, resource design, versioning, and documentation
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Use when designing REST or GraphQL APIs - covers OpenAPI spec, resource design, versioning, and documentation
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Use when orchestrating parallel Claude Code instances across tmux panes with git worktree isolation — managing multiple concurrent development tasks visually
Use when production incident occurs, alerts fire, service degradation detected, or on-call escalation needed - guides systematic organizational response before technical fixes
Use when conducting manual PR reviews - provides structured checklist covering security, performance, maintainability, and code quality dimensions with anti-sycophancy principles
Run local CI checks and ship changes — create branch, commit, push, and PR. Optionally link to a GitHub issue. Use when changes are ready to ship.
Use when encountering any bug, test failure, or unexpected behavior, before proposing fixes
Architecture guide using Next.js App Router's Parallel Routes for Widget-Slot pattern. Separates static layouts from dynamic widgets to achieve separation of concerns, fault isolation, and plug-and-play development.
| name | api-design |
| description | Use when designing REST or GraphQL APIs - covers OpenAPI spec, resource design, versioning, and documentation |
Design APIs that are consistent, predictable, and well-documented. This skill covers REST and GraphQL API design patterns.
Core principle: APIs are contracts. Once published, breaking changes are expensive.
Use this skill:
Not needed for:
✅ Good ❌ Bad
-----------------------------------------
GET /users GET /getUsers
GET /users/{id} GET /user?id=123
POST /users POST /createUser
PUT /users/{id} POST /updateUser
DELETE /users/{id} GET /deleteUser/{id}
GET /users/{id}/orders GET /getUserOrders
Rules:
/users not /user/users/{id}/orders/user-profiles not /userProfiles| Method | Purpose | Idempotent | Safe |
|---|---|---|---|
| GET | Retrieve resource | Yes | Yes |
| POST | Create resource | No | No |
| PUT | Replace resource | Yes | No |
| PATCH | Partial update | Yes* | No |
| DELETE | Remove resource | Yes | No |
*PATCH is idempotent if using JSON Patch/Merge Patch format.
2xx Success
-----------------------------------------
200 OK - GET/PUT/PATCH success, body contains data
201 Created - POST success, Location header has URL
204 No Content - DELETE success, no body
4xx Client Error
-----------------------------------------
400 Bad Request - Invalid input (validation failed)
401 Unauthorized - Authentication required
403 Forbidden - Authenticated but not allowed
404 Not Found - Resource doesn't exist
409 Conflict - State conflict (duplicate, version mismatch)
422 Unprocessable - Valid syntax but semantic error
5xx Server Error
-----------------------------------------
500 Internal Error - Unexpected server error
502 Bad Gateway - Upstream service failed
503 Unavailable - Temporary overload
Success Response:
{
"data": {
"id": "123",
"name": "Example"
},
"meta": {
"requestId": "abc-123",
"timestamp": "2024-01-15T10:30:00Z"
}
}
Collection Response:
{
"data": [
{ "id": "1", "name": "First" },
{ "id": "2", "name": "Second" }
],
"meta": {
"total": 100,
"page": 1,
"pageSize": 20,
"hasNext": true
}
}
Error Response:
{
"error": {
"code": "VALIDATION_ERROR",
"message": "Invalid input data",
"details": [
{ "field": "email", "message": "Invalid email format" }
]
},
"meta": {
"requestId": "abc-123",
"timestamp": "2024-01-15T10:30:00Z"
}
}
| Strategy | Example | Pros | Cons |
|---|---|---|---|
| URI Path | /v1/users | Clear, cacheable | URL changes |
| Header | Accept: application/vnd.api+json;version=1 | Clean URLs | Hidden |
| Query Param | /users?version=1 | Easy to test | Pollutes params |
Recommended: URI Path versioning for simplicity and clarity.
/v1/users # Version 1
/v2/users # Version 2 (breaking changes)
When to increment version:
Non-breaking (no version bump):
openapi: 3.1.0
info:
title: User API
version: 1.0.0
description: User management endpoints
paths:
/users:
get:
summary: List users
operationId: listUsers
parameters:
- name: page
in: query
schema:
type: integer
default: 1
- name: pageSize
in: query
schema:
type: integer
default: 20
maximum: 100
responses:
'200':
description: Success
content:
application/json:
schema:
$ref: '#/components/schemas/UserListResponse'
post:
summary: Create user
operationId: createUser
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CreateUserRequest'
responses:
'201':
description: Created
headers:
Location:
schema:
type: string
content:
application/json:
schema:
$ref: '#/components/schemas/UserResponse'
'400':
description: Validation error
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
components:
schemas:
User:
type: object
required:
- id
- email
properties:
id:
type: string
format: uuid
email:
type: string
format: email
name:
type: string
createdAt:
type: string
format: date-time
ErrorResponse:
type: object
required:
- error
properties:
error:
type: object
required:
- code
- message
properties:
code:
type: string
message:
type: string
details:
type: array
items:
type: object
properties:
field:
type: string
message:
type: string
type Query {
user(id: ID!): User
users(filter: UserFilter, pagination: Pagination): UserConnection!
}
type Mutation {
createUser(input: CreateUserInput!): CreateUserPayload!
updateUser(id: ID!, input: UpdateUserInput!): UpdateUserPayload!
deleteUser(id: ID!): DeleteUserPayload!
}
type User {
id: ID!
email: String!
name: String
orders(first: Int, after: String): OrderConnection!
createdAt: DateTime!
}
# Relay-style connection for pagination
type UserConnection {
edges: [UserEdge!]!
pageInfo: PageInfo!
totalCount: Int!
}
type UserEdge {
cursor: String!
node: User!
}
type PageInfo {
hasNextPage: Boolean!
hasPreviousPage: Boolean!
startCursor: String
endCursor: String
}
# Input types
input CreateUserInput {
email: String!
name: String
}
# Payload types with union for errors
type CreateUserPayload {
user: User
errors: [UserError!]
}
type UserError {
field: String
message: String!
code: String!
}
// ❌ Bad: N+1 queries
const resolvers = {
User: {
orders: async (user) => {
// Called once per user - N queries
return db.orders.findByUserId(user.id);
}
}
};
// ✅ Good: DataLoader batching
import DataLoader from 'dataloader';
const orderLoader = new DataLoader(async (userIds) => {
// Single batched query
const orders = await db.orders.findByUserIds(userIds);
return userIds.map(id => orders.filter(o => o.userId === id));
});
const resolvers = {
User: {
orders: async (user) => orderLoader.load(user.id)
}
};
// Prevent expensive queries
const complexityConfig = {
maximumComplexity: 1000,
scalarCost: 1,
objectCost: 10,
listFactor: 10, // Multiply by list size
};
// Example: users(first: 100) { orders(first: 50) { ... } }
// Complexity: 10 + (100 * (10 + (50 * 10))) = 51,010 (rejected)
HTTP/1.1 200 OK
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95
X-RateLimit-Reset: 1704067200
# When exceeded
HTTP/1.1 429 Too Many Requests
Retry-After: 60
| Strategy | Description | Use Case |
|---|---|---|
| Fixed Window | X requests per minute | Simple APIs |
| Sliding Window | Rolling window | More accurate |
| Token Bucket | Refill tokens over time | Burst-friendly |
| Leaky Bucket | Constant output rate | Smooth traffic |
Client → API Gateway → Microservices
↓
- Authentication
- Rate Limiting
- Request Routing
- Response Caching
- Request/Response Transform
- Circuit Breaker
Before shipping an API:
| Mistake | Fix |
|---|---|
| Verbs in URLs | Use nouns: /users not /getUsers |
| Inconsistent naming | Pick one: camelCase or snake_case |
| Missing pagination | Always paginate lists |
| No error codes | Use machine-readable codes |
| Breaking changes | Version the API |
| Missing rate limits | Protect against abuse |
| N+1 in GraphQL | Use DataLoader |
| No request IDs | Add for debugging |
REST
────────────────────────────────────
GET /resources List all
GET /resources/{id} Get one
POST /resources Create
PUT /resources/{id} Replace
PATCH /resources/{id} Update
DELETE /resources/{id} Remove
GraphQL
────────────────────────────────────
Query Read operations
Mutation Write operations
Subscription Real-time updates
Connections (Relay)
────────────────────────────────────
edges List of edge objects
node The actual object
cursor Pagination cursor
pageInfo hasNextPage, etc.