设计难以误用的 API
Source: Dev.to
对 API 使用者的假设
在设计 API 时,不要假设:
- 使用者会仔细阅读文档。
- 输入总是有效的。
- 调用总是按正确的顺序进行。
而应该假设:
- 有人会误解它。
- 有人会跳过验证。
- 有人会不加思考地复制粘贴示例。
一个好的 API 不依赖“被正确使用”。它 通过设计强制正确性。
含糊的 API 易导致误用
错误示例
POST /updateUser
这会更新什么?
- 姓名?
- 邮箱?
- 密码?
- 全部?
更好的示例
PATCH /users/{id}/email
现在:
- 意图清晰。
- 范围受限。
- 误用变得更难。
如果一个端点可以“做太多事”,最终一定会做错事。高级工程师会设计出 无效状态不可出现 的 API。
为一致状态而设计
有问题的负载
{
"status": "active",
"deleted": true
}
用户不可能既是 active 又是 deleted。API 应该拒绝这种矛盾的输入。
期望的设计
- API 不接受冲突的字段。
- 数据模型阻止不可能的状态。
如果你的 API 允许矛盾的数据,错误不在客户端,而在设计本身。
处理无效输入
静默行为(危险)
- 缺少字段 → 使用默认值
- 无效输入 → 被忽略
- 部分失败 → 返回成功响应
这会让 bug 隐藏起来。
推荐做法
- 大声拒绝无效输入。
- 返回清晰的错误信息。
- 快速、提前失败。
API 应该通过明确的错误教会使用者正确使用它们。
避免 “魔法” 行为
魔法 API 起初看起来很方便——但后期会很痛苦。
魔法行为的例子
- 未声明就自动创建资源。
- 在没有限制的情况下静默重试。
- 根据隐藏标志改变行为。
只要有重要的行为发生,就必须显式说明。
幂等性与安全重试
在真实系统中:
- 请求会被重试。
- 客户端会超时。
- 网络会失效。
如果调用同一个 API 两次会产生意外副作用,生产环境就会出问题。
设计指南
- 重复请求是安全的。
- 重复调用不会破坏状态。
- 客户端不需要复杂的重试逻辑。
仅此一项就能防止大量生产事故。
防止误解
六个月后使用你 API 的人可能:
- 不是你本人。
- 不了解最初的上下文。
- 正在承受压力。
自问:
- 这个 API 会被误解吗?
- 会被错误顺序调用吗?
- 误用会导致数据损坏吗?
如果答案是“是”,就需要重新设计。
真实的 bug 示例
POST /processPayment
调用两次 → 双倍扣费。
更好的设计
- 将意图与执行分离。
- 要求幂等性键。
- 明确副作用。
前期的额外工作可以在后期避免事故。
最后要点
API 是合同,而不仅仅是端点。一个设计良好的 API:
- 限制出错的可能性。
- 让正确使用变得显而易见。
- 让错误使用变得困难。
- 保护系统免受人为错误的影响。
高级工程师不仅设计能工作的 API——他们设计 难以误用 的 API。