用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
直接命令不会经过审查 Prompt;运行前请先检查来源。
npx skills add https://github.com/autohandai/community-skills --skill api-design-restful命令会保持在同一行。复制前请横向滚动并检查完整内容。
想先保存到本地?可下载 SkillsMP 当前能够提供的文件。
基于 SOC 职业分类
正在显示 SKILL.md
| name | api-design-restful |
| description | RESTful API design patterns, error handling, and documentation |
| license | MIT |
| compatibility | nodejs 18+, express 4+, fastify 4+ |
| allowed-tools | read_file write_file apply_patch search_with_context run_command |
# Collection resources
GET /api/v1/users # List users
POST /api/v1/users # Create user
# Individual resources
GET /api/v1/users/:id # Get user
PUT /api/v1/users/:id # Replace user
PATCH /api/v1/users/:id # Update user
DELETE /api/v1/users/:id # Delete user
# Nested resources
GET /api/v1/users/:id/posts # User's posts
POST /api/v1/users/:id/posts # Create post for user
# Filtering, sorting, pagination
GET /api/v1/users?status=active&sort=-createdAt&page=2&limit=20
interface SuccessResponse<T> {
success: true;
data: T;
meta?: {
page?: number;
limit?: number;
total?: number;
totalPages?: number;
};
}
// Example
{
"success": true,
"data": { "id": "123", "name": "John" },
"meta": { "requestId": "abc-123" }
}
interface ErrorResponse {
success: false;
error: {
code: string; // Machine-readable code
message: string; // Human-readable message
details?: unknown; // Field-level errors
};
}
// Example
{
"success": false,
"error": {
"code": "VALIDATION_ERROR",
"message": "Invalid request body",
"details": {
"email": "Invalid email format",
"age": "Must be a positive number"
}
}
}
// Success
200 OK // Successful GET, PUT, PATCH
201 Created // Successful POST
204 No Content // Successful DELETE
// Client Errors
400 Bad Request // Validation errors
401 Unauthorized // Missing/invalid auth
403 Forbidden // Insufficient permissions
404 Not Found // Resource doesn't exist
409 Conflict // Duplicate/state conflict
422 Unprocessable // Semantic errors
429 Too Many Reqs // Rate limited
// Server Errors
500 Internal Error // Unexpected server error
503 Unavailable // Service temporarily down
import express from 'express';
const app = express();
// Async handler wrapper
const asyncHandler = (fn: RequestHandler) => (req, res, next) =>
Promise.resolve(fn(req, res, next)).catch(next);
// Controller
const getUsers = asyncHandler(async (req, res) => {
const { page = 1, limit = 20, status } = req.query;
const { users, total } = await userService.findAll({ page, limit, status });
res.json({
success: true,
data: users,
meta: { page, limit, total, totalPages: Math.ceil(total / limit) }
});
});
// Error handler middleware
app.use((err, req, res, next) => {
const status = err.status || 500;
res.status(status).json({
success: false,
error: {
code: err.code || ,
: err. || ,
...(process.. === && { : err. })
}
});
});
import { z } from 'zod';
const createUserSchema = z.object({
email: z.string().email(),
name: z.string().min(2).max(100),
role: z.enum(['user', 'admin']).default('user'),
});
// Middleware
const validate = (schema: z.ZodSchema) => (req, res, next) => {
const result = schema.safeParse(req.body);
if (!result.success) {
return res.status(400).json({
success: false,
error: {
code: 'VALIDATION_ERROR',
message: 'Invalid request body',
details: result.error.flatten().fieldErrors
}
});
}
req.body = result.data;
next();
};
app.post(, (createUserSchema), createUser);
// JWT middleware
const authenticate = asyncHandler(async (req, res, next) => {
const token = req.headers.authorization?.replace('Bearer ', '');
if (!token) {
throw new ApiError(401, 'UNAUTHORIZED', 'Missing auth token');
}
const payload = await verifyToken(token);
req.user = payload;
next();
});
// Role-based authorization
const authorize = (...roles: string[]) => (req, res, next) => {
if (!roles.includes(req.user.role)) {
throw new ApiError(403, 'FORBIDDEN', 'Insufficient permissions');
}
next();
};
app.delete('/users/:id', authenticate, authorize('admin'), deleteUser);
import rateLimit from 'express-rate-limit';
const limiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 minutes
max: 100,
standardHeaders: true,
legacyHeaders: false,
handler: (req, res) => {
res.status(429).json({
success: false,
error: {
code: 'RATE_LIMITED',
message: 'Too many requests, please try again later'
}
});
}
});
app.use('/api/', limiter);
/users not /user)/api/v1/)