一键导入
api-design
Use this skill when designing or implementing REST APIs, endpoints, routes, or controllers.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Use this skill when designing or implementing REST APIs, endpoints, routes, or controllers.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
This skill should be used when the user asks to "run glab commands", "create a GitLab issue", "create a merge request", "check pipeline status", "manage GitLab projects", "create a release", or mentions glab, GitLab CLI, gitlab-cli, merge request, MR, GitLab pipeline, GitLab CI, GitLab issue keys, or gitlab operations via the command line.
Use this skill when the user asks about Conductor concepts, workflow patterns, track lifecycle, plan structures, or context-driven development principles. Also activate when working with conductor/ directory files or when implementing tasks following TDD and verification protocols.
This skill should be used when the user asks to "run acli jira commands", "create a Jira issue", "search Jira issues", "manage Jira projects", "transition Jira status", "check jira issue", "consistent with jira issue", or mentions ACLI, Atlassian CLI, Jira CLI, Jira issue keys (e.g. KAN-1, PROJ-123), or jira workitem/project/board/sprint operations via the command line.
Use this skill when working with Java code, Optional handling, CompletableFuture, records, sealed classes, or virtual threads.
Use this skill when writing tests, implementing TDD, or setting up test infrastructure.
Use this skill when working with TypeScript code, type definitions, interfaces, generics, or async patterns.
| name | api-design |
| description | Use this skill when designing or implementing REST APIs, endpoints, routes, or controllers. |
| version | 1.0.0 |
Guidance for designing and implementing RESTful APIs. Covers URL conventions, HTTP methods, error handling, versioning, and common patterns.
# Good - plural nouns, lowercase, hyphens
GET /api/v1/users
GET /api/v1/users/:id
GET /api/v1/users/:id/orders
GET /api/v1/order-items
# Avoid - verbs, mixed case, underscores
GET /api/v1/getUsers
GET /api/v1/User/:id
POST /api/v1/create_order
| Method | Purpose | Idempotent | Request Body |
|---|---|---|---|
| GET | Read resource(s) | Yes | No |
| POST | Create resource | No | Yes |
| PUT | Replace resource | Yes | Yes |
| PATCH | Partial update | Yes | Yes |
| DELETE | Remove resource | Yes | No |
# Collection operations
GET /api/v1/users # List all
POST /api/v1/users # Create one
# Single resource
GET /api/v1/users/:id # Get one
PUT /api/v1/users/:id # Replace one
PATCH /api/v1/users/:id # Update one
DELETE /api/v1/users/:id # Delete one
# Nested resources
GET /api/v1/users/:id/orders
POST /api/v1/users/:id/orders
# Actions (when REST doesn't fit)
POST /api/v1/users/:id/activate
POST /api/v1/orders/:id/cancel
{
"error": {
"code": "VALIDATION_ERROR",
"message": "Request validation failed",
"details": [
{
"field": "email",
"message": "Invalid email format"
}
],
"requestId": "req_abc123"
}
}
# Success
200 OK - Successful GET, PUT, PATCH, DELETE
201 Created - Successful POST creating resource
204 No Content - Successful DELETE with no body
# Client Errors
400 Bad Request - Invalid request syntax/body
401 Unauthorized - Missing/invalid authentication
403 Forbidden - Authenticated but not authorized
404 Not Found - Resource doesn't exist
409 Conflict - Resource state conflict
422 Unprocessable - Validation errors
# Server Errors
500 Internal Error - Unexpected server error
502 Bad Gateway - Upstream service error
503 Unavailable - Service temporarily down
// Error class hierarchy
class ApiError extends Error {
constructor(
public code: string,
public message: string,
public statusCode: number,
public details?: unknown[]
) {
super(message);
}
}
class ValidationError extends ApiError {
constructor(details: { field: string; message: string }[]) {
super('VALIDATION_ERROR', 'Request validation failed', 422, details);
}
}
class NotFoundError extends ApiError {
constructor(resource: string, id: string) {
super('NOT_FOUND', `${resource} with id ${id} not found`, 404);
}
}
// Global error handler
function errorHandler(err: Error, req: Request, res: Response) {
if (err instanceof ApiError) {
return res.status(err.statusCode).json({
error: {
code: err.code,
message: err.message,
details: err.details,
requestId: req.id
}
});
}
// Unexpected error - log and return generic message
logger.error('Unhandled error', { error: err, requestId: req.id });
return res.status(500).json({
error: {
code: 'INTERNAL_ERROR',
message: 'An unexpected error occurred',
requestId: req.id
}
});
}
GET /api/v1/users
GET /api/v2/users
// Version-specific routers
const v1Router = Router();
const v2Router = Router();
v1Router.get('/users', getUsersV1);
v2Router.get('/users', getUsersV2);
app.use('/api/v1', v1Router);
app.use('/api/v2', v2Router);
// Deprecation header
res.setHeader('Deprecation', 'true');
res.setHeader('Sunset', 'Sat, 01 Jan 2025 00:00:00 GMT');
res.setHeader('Link', '</api/v2/users>; rel="successor-version"');
// Request
GET /api/v1/users?limit=20&cursor=eyJpZCI6MTIzfQ
// Response
{
"data": [...],
"pagination": {
"hasMore": true,
"nextCursor": "eyJpZCI6MTQzfQ",
"prevCursor": "eyJpZCI6MTAzfQ"
}
}
// Request
GET /api/v1/users?page=2&limit=20
// Response
{
"data": [...],
"pagination": {
"page": 2,
"limit": 20,
"total": 150,
"totalPages": 8
}
}
// Single resource
res.status(200).json({ data: user });
// Collection
res.status(200).json({
data: users,
pagination: { ... }
});
// Created resource
res.status(201).json({ data: newUser });
// No content
res.status(204).send();
# Filtering
GET /api/v1/users?status=active&role=admin
# Sorting
GET /api/v1/users?sort=createdAt:desc,name:asc
# Field selection
GET /api/v1/users?fields=id,name,email