💡 Key Takeaways
- Resource Naming and URI Design: The Foundation That Everyone Gets Wrong
- HTTP Methods and Status Codes: Speaking the Language Correctly
- Request and Response Design: The Devil in the Details
- Error Handling: When Things Go Wrong (And They Will)
三年前,我目睹一家初创公司耗尽230万美元的资金,因为他们的API无法扩展到超过10,000个用户。问题不在于他们的基础设施或数据库设计,而在于他们的REST API架构。作为一个在过去14年中为从小型初创公司到《财富》500强企业构建和维护API的人,我看到这种模式反复出现,次数多到我不愿意计算。我是马库斯·陈,一家大型金融科技公司的首席API架构师,我设计的REST API现在每月处理超过470亿个请求。今天,我分享的实用清单本可以拯救那家初创公司,或者可能会拯救你们的公司。
💡 关键要点
- 资源命名和URI设计:每个人都搞错的基础
- HTTP方法和状态码:正确理解语言
- 请求和响应设计:细节中的魔鬼
- 错误处理:当事情出错时(而且它们会出错)
自我开始从事API开发以来,该领域的格局发生了剧烈变化。早在2011年,如果你的API能够返回JSON并处理基本的CRUD操作,你就领先了。在2026年,标准高得惊人。你的API需要安全、高效、可观察和开发者友好——同时处理五年前不存在的边缘情况。这并不是来自阅读几篇博客文章的理论建议。这是来自一个在凌晨3点调试生产事件、优化每日耗费数千云计算费用的端点,以及培训数十名工程师学习实际有效的API设计原则的人的实战经验。
资源命名和URI设计:每个人都搞错的基础
让我先从一个看似基本但连经验丰富的开发者都容易出错的地方开始:资源命名。上个季度,我审查了我们组织中23个不同团队的API。十九个团队的命名规范不一致,使得他们的API更难使用和维护。这不仅仅是美观问题——糟糕的命名直接影响开发者体验,进而导致集成时间延长和更多支持请求。
基本原则是:你的URI应该表示资源,而不是动作。使用名词,而不是动词。我经常看到这个错误:像/getUser或/createOrder这样的端点。这些是伪装成REST的RPC风格端点。正确的方法是使用HTTP方法来指示动作:GET /users/123或POST /orders。这可能听起来啰嗦,但这很重要。当我将我们的支付处理API重构,以始终遵循这种模式时,与新合作伙伴的集成时间从平均8.3天降至4.1天。
集合的名称应使用复数名词。始终如此。我不在乎它是否在语法上感觉尴尬——一致性胜过语法。你的端点应该是/users,而不是/user。当你混合单数和复数形式时,你迫使开发者记住任意的决定。我见过团队花费几个小时在会议上争论端点应该是单数还是复数。给自己省点麻烦:对于集合,始终使用复数。
层次关系应在你的URI结构中反映,但不要超过三层。如/users/123/orders/456/items/789就变得不易管理。在那时,考虑将items作为顶级资源并进行过滤:/items?orderId=456。我在创建一个有五层嵌套的电子商务API时吃到了这个苦头。代码变得难以维护,我们花了两个月进行了重构。
在URI中使用连字符,而不是下划线。这是一个小细节,可以提高可读性:/order-items比/order_items更易读。更重要的是,一些系统对下划线的处理不同,而连字符则是普遍安全的。保持所有内容为小写。URI中的混合大小写可能会引发麻烦,因为某些系统是区分大小写的,而其他则不是。
从第一天起就为你的API版本化。我无法强调这一点的重要性。使用URI版本控制,例如/v1/users或/v2/orders。我试过头部版本控制、查询参数版本控制和内容协商。URI版本控制是最简单且最少造成麻烦的方法。当我们启动API时没有版本控制,六个月内我们就给自己画上了死胡同。破坏性更改变得无法部署,而不会对现有集成造成混乱。
HTTP方法和状态码:正确理解语言
如果资源命名是基础,HTTP方法和状态码就是REST API的语法。正确使用它们不是可选的——这是你与API消费者沟通意图和结果的方式。我审查了数百个API,其中开发者对HTTP方法的使用把它们当作建议而非规范。这会造成混淆,打破缓存,使你的API变得不可预测。
"您的API的资源命名不仅仅是为了美观——这关系到开发者在几天与几周集成之间的差异,这直接影响你的底线。”
GET请求必须安全且幂等。安全意味着它们不会修改服务器状态。幂等意味着多次调用它们产生相同的结果。我曾经接手过一个API,其中GET请求会创建数据库记录。这造成的混乱可谓惊人——浏览器预取和链接爬虫创建了成千上万的虚假记录。我们花了三周时间来清理这个烂摊子并修复设计。
POST用于创建资源。当你POST到/orders时,你正在创建一个新订单。响应应返回201 Created,并包含指向新资源的Location头:Location: /orders/789。在响应体中包含创建的资源。这可以避免客户端进行额外的GET请求。在我们的订单处理系统中,这一简单优化将API调用减少了31%,显著提高了感知性能。
PUT用于完整更新,应该是幂等的。如果你对/users/123进行十次相同的数据PUT,结果应该与一次的结果相同。PATCH用于部分更新。当客户端只需要发送更改的字段时使用PATCH。这可以减少有效载荷大小,使更新更高效。在我们的用户配置文件API中,将个人资料更新从PUT切换到PATCH将平均有效载荷大小从4.2KB减少到0.8KB。
DELETE在成功删除时应返回204 No Content。一些开发者返回200 OK并附带确认消息,但204在语义上更正确——没有内容返回,因为资源不存在了。DELETE也应该是幂等的。删除已经删除的资源应返回204,而不是404。这可以防止分布式系统中的竞争条件。
状态码比你想的更重要。成功的GET、PUT和PATCH请求使用200 OK。成功的POST请求使用201 Created。成功的DELETE请求使用204 No Content。