# 面向持续演进产品的 API 设计

构建支持变更的接口，而不让每次发布都变成协调迁移。

Published: 2024-09-18

## 建模领域，而非屏幕

界面比其背后的概念变化更快。围绕特定屏幕构建的 API 往往暴露呈现状态，并在新客户端出现时迫使重复端点。从稳定的领域资源、其生命周期以及业务认可的操作开始。

这不要求理论纯粹。面向产品的 API 可为旅程聚合数据，但聚合应有清晰目的与所有权。避免直接泄漏数据库表；存储结构是最终需要变更的实现细节。

## 兼容性是一项功能

消费者按不同节奏部署，尤其是移动应用与外部集成。加性变更通常更安全：新的可选字段、新资源，以及带容忍读取器的新枚举值。移除或重新定义现有行为需要迁移计划、遥测与公布的结束日期。

当语义真正分叉时，版本化有用，但版本号不能替代兼容性纪律。版本化 API 仍可通过变更顺序、错误行为、限制或授权让消费者措手不及。维护机器可读 schema，并对照它测试代表性消费者。

- 安全处理未知枚举值
- 文档化可空性与默认值
- 对关键消费者使用契约测试
- 在移除前衡量弃用字段的使用情况

## 变更需要身份

在不可靠网络上，重试不可避免。对重要变更，接受限定于调用方与操作的幂等键。存储结果，使重复请求返回原始结果，而非再次执行动作。

长时间运行的工作应返回带显式状态的操作资源。客户端可轮询或订阅，而无需保持脆弱请求打开。这也改善支持：系统可解释工作是排队、进行中、已完成还是失败，以及原因。

## 授权属于契约

认证确立身份；授权决定该身份是否可对资源执行操作。在服务器上以最窄有意义边界强制执行。在客户端隐藏按钮是界面行为，不是访问控制。

多租户系统需要不能由客户端自由提供并信任的租户上下文。从已验证成员资格派生范围，在每次资源访问时校验所有权，并以足够上下文记录管理动作，以供审计与调查。

## 为消费者理解而优化

一致命名、可预测分页、有用错误、示例与清晰变更日志，比巧妙的协议选择更能减少集成时间。当消费者无需了解其内部历史即可正确使用时，API 才成功。

设计评审应包含客户端工程师与运维场景。接口的寿命长于首次实现，因此把精度花在最难变更的部分：标识符、语义、授权与生命周期。
