API Design

2026-08-161 引用

API 是协作边界,不是内部实现的直接映射。

API Design = Boundary Design

核心目标

好的 API = 易理解 + 可演进 + 可安全运行。

  • 易理解:命名、资源和行为符合已有约定;常见任务不需要 workaround。
  • 可演进:优先向后兼容的增量变更;把不稳定的实现细节藏在契约后面。
  • 可安全运行:明确超时、重试、幂等、限流、权限和错误语义。

设计原则

  1. 先建模,再选协议:先明确资源、关系和动作,再决定 REST、RPC 或事件。
  2. 优先简单路径:让最常见的调用最短、最直观;复杂需求再提供扩展点。
  3. 行为要可预测:同一概念使用同一命名、状态和错误格式。
  4. 契约小而稳定:只暴露调用方真正需要的字段;避免泄露内部表结构。
  5. 显式表达意图:区分创建、更新、删除和动作,不用隐晦参数改变语义。

常用约定

http
GET    /users/{id}          # read
POST   /users               # create
PATCH  /users/{id}          # partial update
DELETE /users/{id}          # delete
POST   /users/{id}:disable  # action that is not CRUD
  • 列表默认分页;优先使用稳定的 pageToken,不要依赖深分页的 offset
  • 部分更新使用字段掩码或明确的 PATCH 语义,避免并发下的读改写覆盖。
  • 创建和有副作用的请求支持 Idempotency-Key,使客户端可以安全重试。
  • 错误至少包含稳定的 code、可读的 message 和可定位的 request_id
  • 不把 200 OK 当作所有结果;正确使用 2012022044xx5xx

演进与安全

  • 新增字段、端点和可选能力通常是兼容的;删除、改名、改变含义通常不是。
  • 破坏性变更应显式版本化,并给出迁移和废弃周期。
  • 服务端必须校验输入、鉴权每个操作,并限制请求大小、频率和资源消耗。
  • 重试只适用于可判断安全的错误;超时不代表服务端没有执行成功。

提交前检查

  • 调用方能否仅凭契约完成任务?
  • 常见调用是否简单,异常和边界是否明确?
  • 网络失败、重复请求和并发更新是否安全?
  • 新旧客户端同时运行时,契约是否仍兼容?
  • 是否暴露了不必要的实现细节、权限或数据?

评论