
claude-skills 全栈安全视角下的 REST API 设计标准URL、状态码、错误、分页、版本、限流与文档化实战【免费下载链接】claude-skills67 Specialized Skills for Full-Stack Developers. Transform Claude Code into your expert pair programmer.项目地址: https://gitcode.com/GitHub_Trending/claud/claude-skills本篇技术指南以 claude-skills 仓库中 fullstack-guardian 技能的核心参考文档 api-design-standards.md 为主体骨架系统讲解在开发全栈应用时应当遵循的 RESTful API 设计规范。文章覆盖 URL 结构、HTTP 状态码语义、标准化错误响应、分页、版本控制、限流、CORS、请求校验与 OpenAPI 文档化等完整议题并串联仓库内 security-checklist.md、error-handling.md 等配套参考提供可直接落地的 TypeScript/Python 代码示例。读完本文你将能按照统一的工程化标准设计、实现并文档化一套安全、一致、可扩展的 REST API。一、这套标准在 claude-skills 中的定位fullstack-guardian 是 claude-skills 仓库中一个安全导向的全栈开发技能SKILL.md其定位是同时从前端、后端、安全三个视角实现跨全栈的功能。在它的 Reference Guide 中API 设计规范references/api-design-standards.md明确用于REST/GraphQL APIs、版本控制、CORS、校验等场景与 design-template.md三视角设计模板、security-checklist.md每功能安全清单形成互补前者解决API 长得对不对后者解决API 安不安全。需要特别强调该技能的核心约束MUST DO / MUST NOT DO对 API 设计的直接影响服务端与客户端都要做输入校验不能只信任客户端校验必须使用参数化查询防止 SQL 注入必须对输出做清理防止 XSS每一层都要有正确的错误处理不得在 API 响应中暴露敏感数据。下面各节的每一条约定最终都要服务于这三条安全底线。二、RESTful URL 结构约定Collection 与 Resource标准要求用复数名词表示资源集合Collection用单数资源标识符操作单个资源ResourceGET /api/users # 列出所有用户 POST /api/users # 创建用户 GET /api/users/:id # 获取单个用户 PUT /api/users/:id # 全量更新 PATCH /api/users/:id # 部分更新 DELETE /api/users/:id # 删除用户关键语义约定POST作用于集合创建资源GET/PUT/PATCH/DELETE作用于单个资源PUT是全量替换PATCH是部分更新——两者在文档中被明确区分不要混用资源名统一使用复数名词/api/users而不是/api/user。嵌套资源当资源之间存在从属关系时使用嵌套路径表达层级GET /api/users/:id/posts # 获取某用户的所有文章 POST /api/users/:id/posts # 为某用户创建文章 GET /api/posts/:id/comments # 获取某文章的所有评论嵌套路径适合表达归属关系明确、层级不深的资源。若层级过深超过两层或关系复杂文档中并未给出强制规则可以结合业务权衡是否改用查询参数或扁平化设计。三、HTTP 状态码语义状态码是客户端理解请求结果的第一语言必须语义化使用而非随意返回200// 成功类 200 OK // GET、PUT、PATCH 成功 201 Created // POST 成功资源已创建 204 No Content // DELETE 成功无响应体 202 Accepted // 异步操作已排队 // 客户端错误类 400 Bad Request // 请求格式错误如畸形 JSON 401 Unauthorized // 需要认证 403 Forbidden // 已认证但无权限 404 Not Found // 资源不存在 409 Conflict // 资源冲突如邮箱重复 422 Unprocessable // 业务/字段校验失败 429 Too Many Requests // 超出限流 // 服务端错误类 500 Internal Server Error // 未处理异常 502 Bad Gateway // 上游服务失败 503 Service Unavailable // 临时不可用如维护中对照仓库内 error-handling.md 的快速参考表可以看到同一套状态码在何时使用上的细化401对应缺少/无效 token403对应权限不足409对应重复邮箱422对应邮箱格式非法等。两篇文档互为补充本标准的重点是语义正确error-handling 的重点是前后端如何消费这些状态码。特别要注意401与403的区分401 表示你是谁未解决未认证403 表示你是谁已解决但没有资格做这件事未授权。四、标准化错误响应统一错误结构为了让前端能够统一解析错误所有错误响应必须遵循同一个结构interface ApiError { error: { code: string; // 机器可读的错误码如 VALIDATION_ERROR message: string; // 人类可读的错误描述 details?: { // 字段级校验错误 [field: string]: string[]; }; requestId: string; // 请求 ID用于支持/排障 timestamp: string; // ISO 8601 时间戳 }; }实例校验失败字段级错误{ error: { code: VALIDATION_ERROR, message: Invalid input data, details: { email: [Must be a valid email address], password: [Must be at least 12 characters] }, requestId: req_abc123, timestamp: 2025-01-15T10:30:00Z } }资源不存在{ error: { code: RESOURCE_NOT_FOUND, message: User not found, requestId: req_def456, timestamp: 2025-01-15T10:31:00Z } }设计要点解读code与message分离前端可以按code做分支逻辑如VALIDATION_ERROR时把details回填到表单message则直接展示给用户details的 value 是字符串数组可容纳同一字段的多条错误例如邮箱同时为空且格式错误requestId对生产环境排障至关重要配合日志系统可快速定位问题请求在 backend-patterns.md 的分布式追踪章节中requestId/traceId也是贯穿链路的核心标识成功响应中不要混入这种错误结构保持成功归成功、失败归失败的一致性。五、分页设计Meta Links 模式查询参数约定分页通过查询参数传递并支持排序与过滤GET /api/users?page1limit20sort-createdAtfilter[role]adminpage页码从 1 开始limit每页条数默认 20sort-createdAt负号表示降序filter[role]admin按字段过滤。响应格式interface PaginatedResponseT { data: T[]; meta: { page: number; limit: number; total: number; totalPages: number; }; links?: { first: string; prev?: string; next?: string; last: string; }; }meta提供分页元信息前端据此渲染分页器、计算是否还有下一页links提供可直接请求的 URLHATEOAS 风格prev/next在不存在时省略可选属性。NestJS 实现示例文档给出了一个可直接复制的 NestJS 控制器实现注意通过DefaultValuePipe提供默认值、ParseIntPipe保证参数为整数Get() async findAll( Query(page, new DefaultValuePipe(1), ParseIntPipe) page: number, Query(limit, new DefaultValuePipe(20), ParseIntPipe) limit: number, ) { const [data, total] await this.service.findAndCount({ page, limit }); return { data, meta: { page, limit, total, totalPages: Math.ceil(total / limit), }, links: { first: /api/users?page1limit${limit}, next: page totalPages ? /api/users?page${page 1}limit${limit} : undefined, last: /api/users?page${totalPages}limit${limit}, }, }; }同样的约定在 common-patterns.md 的 CRUD Read列表 分页章节中再次出现——前端用useQuery以[users, page, limit]作为缓存键发起请求后端返回PaginatedResponseUser前后端契约一致这正是仓库内 integration-patterns.md 所提倡的共享类型防止 API 契约漂移的具体体现。六、API 版本控制URL 路径版本化推荐把版本号放进 URL 路径是最直观、最不易出错的方案客户端可独立升级GET /api/v1/users GET /api/v2/usersExpress 中通过独立路由挂载实现app.use(/api/v1, v1Router); app.use(/api/v2, v2Router);NestJS 中则用控制器级version声明Controller({ version: 1, path: users }) export class UsersV1Controller {} Controller({ version: 2, path: users }) export class UsersV2Controller {}Header 版本化备选方案如果不想污染 URL可以在请求头中携带版本GET /api/users Accept-Version: v2配合中间件解析版本并挂到请求对象上app.use((req, res, next) { const version req.headers[accept-version] || v1; req.apiVersion version; next(); });两种方案各有取舍URL 版本化对浏览器缓存、日志分析、共享链接更友好Header 版本化让 URL 保持纯净但调试与缓存键管理更复杂。标准明确推荐前者后者仅作为备选。七、限流Rate Limiting限流是对抗暴力破解、保护后端资源的第一道防线。它同样出现在 security-checklist.md 的每功能安全检查表中Endpoint rate limited?以及Brute Force → Rate limiting的风险缓解行。按端点差异化配置Express express-rate-limit不同端点应配置不同额度——认证类端点安全敏感性高应设更严格的限制import rateLimit from express-rate-limit; // 通用限流15 分钟窗口内 100 次 const generalLimiter rateLimit({ windowMs: 15 * 60 * 1000, // 15 分钟 max: 100, // 窗口内最多 100 次 message: Too many requests from this IP, }); // 认证端点更严格且成功请求不计入额度 const authLimiter rateLimit({ windowMs: 15 * 60 * 1000, max: 5, // 认证端点最多 5 次 skipSuccessfulRequests: true, }); app.use(/api/, generalLimiter); app.use(/api/auth/, authLimiter);要点skipSuccessfulRequests: true意味着只有失败的登录尝试会消耗额度允许合法用户正常重试。对照快速参考表中Auth: 5/min, General: 100/15min的推荐配置二者保持一致。分布式场景Redis 限流当应用多实例部署时进程内限流会各自计数、失去全局约束需要集中式存储。rate-limiter-flexible配合 Redis 可实现跨实例限流import { RateLimiterRedis } from rate-limiter-flexible; const rateLimiter new RateLimiterRedis({ storeClient: redisClient, keyPrefix: rate-limit, points: 100, // 请求点数 duration: 60, // 60 秒窗口 }); app.use(async (req, res, next) { try { await rateLimiter.consume(req.ip); next(); } catch (error) { res.status(429).json({ error: Too Many Requests }); } });注意此处返回的429与本文第三节的状态码语义表完全对齐。从实现层面看consume → 成功则放行 / 失败则 429这一模式是限流中间件的通用骨架所有后端框架均可移植。八、CORS 配置生产环境白名单CORS 是浏览器端跨域安全的关键开关。生产环境不应使用origin: *的全开配置而要使用显式白名单import cors from cors; const corsOptions { origin: (origin, callback) { const allowedOrigins [ https://app.example.com, https://admin.example.com, ]; if (!origin || allowedOrigins.includes(origin)) { callback(null, true); // 放行同源请求或无 Origin 头如 curl/服务器调用 } else { callback(new Error(Not allowed by CORS)); // 拒绝 } }, credentials: true, // 允许携带 Cookie methods: [GET, POST, PUT, PATCH, DELETE], allowedHeaders: [Content-Type, Authorization], exposedHeaders: [X-Total-Count], // 让前端能读取分页总数等响应头 maxAge: 86400, // 预检请求缓存 24 小时 }; app.use(cors(corsOptions));参数解读credentials: true配合allowedOrigins白名单必须精确匹配否则带 Cookie 的跨域请求会被拦截exposedHeaders列出允许前端 JS 读取的响应头——例如分页实现里若用X-Total-Count头传递总数就必须在此暴露maxAge: 86400可显著减少预检OPTIONS请求次数降低延迟。九、请求/响应校验Schema 驱动Zod 输入校验输入校验是防止注入类攻击SQL 注入、NoSQL 注入、XSS的第一道闸门。标准推荐使用 Zod 定义请求体 schema并在进入业务逻辑前解析import { z } from zod; const createUserSchema z.object({ email: z.string().email(), name: z.string().min(1).max(100), age: z.number().int().min(18).max(120).optional(), role: z.enum([user, admin]).default(user), }); // 中间件解析通过则挂载到 req失败则返回 422 const validate (schema: z.ZodSchema) (req, res, next) { try { req.validatedBody schema.parse(req.body); next(); } catch (error) { res.status(422).json({ error: { code: VALIDATION_ERROR, message: Invalid request data, details: error.errors, // Zod 生成的字段级错误 }, }); } }; app.post(/api/users, validate(createUserSchema), createUserHandler);这个示例把本文的多个约定串联了起来422与错误结构{ error: { code, message, details } }完全符合第四节标准details直接使用 Zod 的error.errors天然是字段级数组与ApiError.details的结构兼容。与安全清单的呼应security-checklist.md 中给出了对应的 Pydantic 版本Python 栈class CreateUser(BaseModel): email: EmailStr name: str Field(min_length1, max_length100) password: str Field(min_length12)同一套校验规则应同时用于前端表单如 React Hook Form zodResolver和后端入口正如 integration-patterns.md 中Shared Validation (Zod)一节所示把 schema 放在共享包packages/shared/schemas.ts中前后端引用同一份定义彻底消除契约漂移。十、API 文档OpenAPI / Swagger 自动生成文档是 API 的用户手册。标准推荐通过装饰器/注解自动生成 OpenAPI 文档避免手写文档与实现脱节。NestJS Swagger 示例import { DocumentBuilder, SwaggerModule } from nestjs/swagger; const config new DocumentBuilder() .setTitle(API Documentation) .setDescription(The API description) .setVersion(1.0) .addBearerAuth() // 声明 Bearer token 认证 .build(); const document SwaggerModule.createDocument(app, config); SwaggerModule.setup(api/docs, app, document); // 装饰端点让文档包含语义信息 ApiOperation({ summary: Create a new user }) ApiResponse({ status: 201, description: User created successfully }) ApiResponse({ status: 422, description: Validation failed }) Post() async create(Body() dto: CreateUserDto) { return this.service.create(dto); }价值要点.addBearerAuth()让文档交互面板支持直接携带 JWT 调试受保护接口ApiResponse把状态码语义201/422 等固化在文档中与本文第三节约定一一对应由于文档从代码生成接口变更时文档不会过期。从仓库技能生态看独立的 api-designer 技能在 references/openapi.md、references/versioning.md、references/pagination.md 中提供了更深入的专题参考需要深度设计时可将两者配合使用若采用 FastAPI/Django 栈仓库中的 code-documenter 在 references/api-docs-fastapi-django.md 中同样覆盖了交互式 API 文档的生成方式。十一、快速参考表AspectStandardExampleURL namingPlural nouns/api/usersnot/api/userHTTP methodsRESTful semanticsGET (read), POST (create), PUT/PATCH (update), DELETEStatus codesSemantic usage200 (success), 201 (created), 422 (validation)ErrorsConsistent format{ error: { code, message, details } }PaginationMeta links{ data, meta: { page, total }, links }VersioningURL path/api/v1/usersRate limitingPer-endpointAuth: 5/min, General: 100/15minCORSWhitelist originsProduction domains onlyValidationSchema-basedZod/Pydantic with detailed errorsDocumentationOpenAPIAuto-generated from decorators这张表是全篇的浓缩每一项都对应上文一个完整小节可以把它当作团队 Code Review 的检查清单来用。十二、把这些标准放进 fullstack-guardian 的工作流标准文档解决的是API 应该长什么样而 fullstack-guardian 技能的核心工作流SKILL.md解决的是如何把标准落到每一次功能开发中Gather requirements收集需求与验收标准Design solution从 Frontend / Backend / Security 三个视角设计Write technical design在specs/{feature}_design.md中写技术设计模板见 design-template.mdSecurity checkpoint编码前先过 security-checklist.mdImplement按标准增量实现、逐个组件测试Hand off移交 Test Master 做 QA、DevOps 做部署。以 SKILL.md 中的最小认证端点示例为例可以清晰地看到 API 设计标准与安全底线的交汇router.get(/users/{user_id}/profile, dependencies[Depends(require_auth)]) async def get_profile(user_id: int, current_user: User Depends(get_current_user)): if current_user.id ! user_id: raise HTTPException(status_code403, detailForbidden) # 参数化查询 —— 不做原始字符串拼接 row await db.fetchone(SELECT id, name, email FROM users WHERE id ?, (user_id,)) if not row: raise HTTPException(status_code404, detailNot found) return ProfileResponse(**row) # 显式响应 schema —— 不泄露密码/token这里示范了本文全部原则的落地形态语义化状态码403/404、显式响应 schema不暴露敏感字段、先授权后访问防止 IDOR 时间侧信道。前端侧则配合统一的apiFetch封装处理401/403/422等错误码——完整的错误消费模式见 error-handling.md。结语从 URL 复数命名、状态码语义、统一错误结构到分页的 MetaLinks 模式、URL 路径版本化、按端点差异化限流、CORS 白名单、Zod/Pydantic 校验与 OpenAPI 自动文档——这套 REST API 设计标准覆盖了全栈开发中前后端接口契约的每一个关键面。它的价值在于一致性错误结构一致、状态码语义一致、分页结构一致前端才能用一套通用逻辑消费所有接口安全加固才能贯穿所有端点。在实际项目中建议以本文第十一节的快速参考表作为评审基准并以 security-checklist.md 作为每个功能的必经关卡二者结合即为 fullstack-guardian 所倡导的安全导向全栈开发的 API 落地范式。【免费下载链接】claude-skills67 Specialized Skills for Full-Stack Developers. Transform Claude Code into your expert pair programmer.项目地址: https://gitcode.com/GitHub_Trending/claud/claude-skills创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考