#速率限制

刚在 Hacker News 上看到一篇关于 API 设计的文章,觉得写得特别实在,很有共鸣,想跟大家分享一下里面的几个关键点,看看对我们现在做的事情有没有启发。 作者的核心思想很简单:一个好的 API,首先是无聊的。 什么叫无聊?就是说它应该非常符合直觉,让调用它的开发者不需要看太多文档,凭着经验就能猜到怎么用。任何需要让开发者花时间去琢磨的聪明或有趣的设计,其实都增加了他们的使用成本。 在这之上,API 的设计总是在两个目标之间找平衡:一是刚才说的易用性,二是为未来考虑的灵活性。因为 API 一旦发布,就很难再改了。 文章里有几个观点,我觉得特别值得我们思考: 第一,也是最重要的一条原则:绝对不要破坏用户的应用。 作者把这称为 API 维护者的神圣职责。一旦我们发布了 API,别人就会依赖它来构建自己的业务。任何破坏性的变更,比如删掉一个字段或者改变它的结构,都会立刻搞垮下游的应用。这不仅仅是技术问题,更是信任问题。 文章里举了 HTTP 协议里那个著名的例子:Referer 这个头,其实是单词 Referrer 的拼写错误。但几十年了,也没人去修正它,因为改动它的代价太大了。这种对稳定性的尊重,是很值得我们学习的。 第二,关于变更和版本控制。 既然不能轻易做破坏性变更,那产品需要迭代时怎么办?答案是版本控制,比如在 URL 里加上 /v1/, /v2/。 但作者也强调,版本控制是必要的恶,是万不得已的最后手段。因为每增加一个版本,我们的维护成本就会翻倍,需要测试、支持和维护的东西越来越多。对用户来说,不同版本的文档也会让他们感到困惑。所以,我们在设计初期就要想得长远一些,尽量避免以后需要用版本控制来收拾烂摊子。 第三,API 的成功最终取决于产品。 这一点我觉得特别真实。API 只是一个工具,一个访问我们服务的窗口。如果我们的产品本身价值够大,就算 API 设计得再烂(作者点名了 Jira 和 Facebook),大家还是会捏着鼻子用。反过来,如果产品本身没人需要,那 API 设计得再优雅也没用。 这对我们的启发是,一个设计混乱的产品,几乎不可能有一个清晰好用的 API。因为 API 只是内部业务逻辑的一层映射。所以,想让 API 变好,首先得把内部的产品模型和逻辑理清楚。 最后,是一些非常具体的实战建议: - 认证要简单:除了支持 OAuth 这种复杂的流程,一定要提供一个简单的 API Key。很多用户可能不是专业的后端工程师,他们只想写个小脚本快速验证一下想法。简单的 API Key 能极大地降低他们的入门门槛。 - 写操作要支持幂等:网络请求总会遇到超时或者失败。用户重试请求时,怎么保证一个操作不会被执行两次?比如重复创建订单。方法就是支持幂等键,让调用方在请求里带上一个唯一的 key,我们后台根据这个 key 来识别和忽略重复的请求。 - 必须有速率限制:用户是通过代码来调用 API 的,一个死循环就可能在瞬间打垮我们的服务。所以,一定要有速率限制来保护系统。同时,最好在响应头里告诉用户他们还剩多少配额,这样他们的程序也能更智能地控制请求频率。 - 分页要用游标:当返回一个很长的列表时,比如几万条记录,用传统的 page=2 这种方式性能会很差,因为数据库在查询时需要数过所有前面的记录。更好的方法是基于游标的分页,客户端的请求会变成“给我 ID 大于 X 的后 20 条记录”,这对数据库来说效率非常高。 总的来说,这篇文章给我的感觉就是非常务实,不谈那些花哨的理论,而是专注于如何构建一个稳定、可信赖、对开发者友好的 API。核心就是:尊重你的用户,把稳定性当做最高优先级,并努力降低他们的使用成本。 大家可以想想,在我们自己的项目里,哪些地方可以借鉴这些经验。分享完了,大家有什么想法吗?