5月27日 16:46

Serverless API 设计有哪些最佳实践?

Serverless 架构改变了 API 的设计与运维方式——函数无状态、冷启动不可控、弹性伸缩自动发生。这些特性决定了 API 设计不能照搬传统单体或微服务思路,需要从请求模型、网关配置、性能策略三个层面重新审视。

API 设计核心原则

RESTful 设计规范

Serverless 函数粒度小、生命周期短,RESTful 风格的约束刚好与之契合:

  • 资源导向路由:用名词表示资源(/users/orders),用 HTTP 方法表达操作(GET 查询、POST 创建、PUT 更新、DELETE 删除)。避免在路径中混入动词,如 /getUser/deleteOrder
  • 统一接口约定:所有端点遵循相同的请求/响应格式,状态码语义一致——201 表示创建成功,204 表示删除成功,422 表示参数校验失败。前端或调用方不需要为每个接口写特殊处理逻辑。
  • 版本控制:将版本号放在 URL 路径(/v1/users)或请求头(Accept: application/vnd.api.v1+json)中。路径版本更直观,适合对外公开 API;请求头版本更 RESTful,适合内部服务。

无状态设计

无状态是 Serverless 的底层约束,API 设计必须顺应这一点:

  • 会话管理:不在函数内存中保存会话状态。使用 JWT Token 将用户信息编码在令牌本身,或用 Redis/DynamoDB 等外部存储托管 session。每次请求携带完整认证信息,函数实例之间无需共享内存。
  • 请求独立性:每个请求自包含所有必要上下文——认证信息、请求参数、关联 ID。不要假设同一用户的连续请求会命中同一个函数实例。
  • 幂等性保障:对于写操作,确保相同的请求重复执行不会产生副作用。创建操作用幂等键(idempotency key)去重,更新操作用条件写入(如 DynamoDB 的 ConditionExpression)防止并发覆盖。

性能优化策略

冷启动和按调用计费是 Serverless 的两个痛点,性能优化围绕它们展开:

  • 响应缓存:对读多写少的接口,在 API Gateway 层启用缓存(TTL 按数据更新频率设置),或在前方部署 CloudFront/CDN 缓存完整响应。这能大幅减少函数调用次数,降低冷启动概率和费用。
  • 批量操作支持:设计批量端点(POST /users/batch),允许单次请求处理多条记录,减少函数调用次数和网络往返。批量上限要合理设置,避免超时。
  • 异步处理:耗时操作(报表生成、邮件发送、文件转码)不要同步等待。API 立即返回 202 Accepted 和一个任务 ID,后台通过 Step Functions 或 SQS 队列异步执行,客户端通过 GET /tasks/{id} 轮询结果。

API Gateway 配置要点

API Gateway 是 Serverless API 的入口,配置质量直接影响安全性和可维护性。

路由配置

  • 路径映射:将 HTTP 路径和方法映射到对应的 Lambda 函数。合理组织路由结构,相关资源嵌套展示(/users/{id}/orders),但避免过深嵌套(超过 3 层会增加理解成本)。
  • 参数验证:在 API Gateway 层配置请求验证器(Request Validator),对路径参数、查询参数、请求体进行格式校验。不合法的请求在网关层就被拦截,不会触发函数调用,既节省费用又减少无效执行。
  • 限流配置:设置 API 级别的限流策略(Throttling),包括速率上限(Rate)和突发上限(Burst)。对公开 API 尤其重要,防止个别消费者占用全部容量。

认证与授权

  • API Key:最简单的认证方式,适合内部服务或受信调用方。API Key 通过请求头 x-api-key 传递,API Gateway 直接校验,无需调用 Lambda。注意 API Key 不等同于安全认证,它更接近访问控制,应结合使用计划(Usage Plan)做配额管理。
  • Amazon Cognito:托管用户池(User Pool),支持注册、登录、密码找回等用户管理流程。前端登录后拿到 JWT,API Gateway 自动验证令牌签名和过期时间,适合面向终端用户的 API。
  • Lambda Authorizer:当认证逻辑超出 Cognito 能力范围时使用。Lambda 函数接收请求信息,执行自定义校验逻辑(如查询数据库、调用内部认证服务),返回 IAM 策略。适合企业内部 SSO、三方 OAuth 等复杂场景。

响应处理

  • CORS 配置:浏览器跨域请求需要正确的 CORS 头。在 API Gateway 中配置 Access-Control-Allow-OriginAccess-Control-Allow-MethodsAccess-Control-Allow-Headers。OPTIONS 预检请求也要正确响应,否则前端跨域调用会失败。
  • 统一错误格式:所有错误响应遵循相同结构,例如 {"error": {"code": "VALIDATION_ERROR", "message": "..."}}。Lambda 函数抛出异常时,通过映射模板将错误统一转换为标准格式返回。
  • 响应转换:使用映射模板(Mapping Template)转换 Lambda 返回值格式。例如函数返回业务数据,网关层自动包装成 {"data": ..., "meta": {...}} 的信封格式,调用方无需关心函数内部结构。

交付级最佳实践

接口文档

使用 Swagger/OpenAPI 规范生成接口文档,确保文档与代码同步。AWS SAM 和 Serverless Framework 都支持在模板中内联定义 API Schema,部署时自动生成文档。文档应覆盖请求参数、响应格式、错误码、调用示例。

监控告警

关键指标必须持续监控:

  • 调用量和错误率:通过 CloudWatch Metrics 跟踪 API 调用次数和 4xx/5xx 错误率。5xx 错误率超过阈值时触发告警。
  • 响应时间:监控 P50/P95/P99 延迟,冷启动导致的延迟飙升需要及时捕获。
  • 并发数和限流拒绝:观察并发执行数是否接近账户限额,被限流拒绝的请求数是否异常增长。

安全防护

  • WAF 配置:在 API Gateway 前部署 AWS WAF,防护 SQL 注入、XSS 跨站脚本、异常流量等常见攻击。设置 IP 黑名单和地理限制,阻断已知恶意来源。
  • 最小权限原则:Lambda 函数的 IAM Role 只授予必要的权限,禁止使用 *:* 全通配策略。
  • 敏感数据保护:不在 URL 路径或查询参数中传递敏感信息(密钥、Token),使用请求头或请求体。启用 API Gateway 的请求日志时,注意脱敏处理。

测试覆盖

为每个 API 端点编写测试用例,覆盖正常路径和边界情况:

  • 单元测试:验证 Lambda 函数的逻辑正确性,Mock 外部依赖。
  • 集成测试:通过 API Gateway 的测试调用功能,验证端到端流程。
  • 契约测试:确保 API 的请求/响应格式符合 OpenAPI 定义,防止破坏性变更。

Serverless 架构下 API 设计的核心思路是:把无状态约束当作设计原则而非限制,让每个请求自包含,让 API Gateway 承担更多网关层的职责,把函数专注于业务逻辑。

标签:Serverless