尽管还有 SOAP、gRPC、GraphQL、Kafka 等标准,REST(表述性状态转移)仍是构建稳健 Web API 的可靠选择。使用 REST 时,设计必须牢记 HTTP 方法、JSON 格式与状态码。对多数 Web API 开发者,遵循 REST 惯例能产出高性能、易用的接口。
来自福特(Ford)内部 API 风格指南的 8 条实战经验。本文编译自 Nordic APIs(作者 Adriano Mota,2019),系统讲清 HTTP 方法、资源定义、URI 规范、版本化与状态码等 REST 设计基本功。
尽管还有 SOAP、gRPC、GraphQL、Kafka 等标准,REST(表述性状态转移)仍是构建稳健 Web API 的可靠选择。使用 REST 时,设计必须牢记 HTTP 方法、JSON 格式与状态码。对多数 Web API 开发者,遵循 REST 惯例能产出高性能、易用的接口。
在福特,我们主要依赖四种 HTTP 方法:GET、POST、DELETE、PUT,它们能覆盖绝大多数操作。
| 方法 | CRUD 操作 | 路径示例 | 说明 |
|---|---|---|---|
| GET | 读取 | /vehicles | 获取资源列表;具体信息用 URI 参数(如 /vehicles/{id}),切勿用 JSON Body 传查询参数 |
| POST | 创建 | /vehicles | 新增资源记录 |
| DELETE | 删除 | /vehicles/{id} | 从库里移除该资源,用参数标识,不用 Body |
| PUT | 更新 | /vehicles/{id} | 更新资源信息,用参数定位、用 Body 传新值 |
资源(resource)是你要操作的实体(即领域)。若领域是 vehicle,URI 就指向 /vehicles。良好的命名约定很有用:在福特,领域实体/资源名一律用复数(vehicles 而非 vehicle),该规则同样适用于子层级与子资源。
有时资源需要某个特定属性,但 URI 不足以表达,这时用子资源(sub-resource)。例如已有 /api/vehicle,要取该车的 parts(零部件)信息,可建子资源 /api/vehicle/{id}/parts。对应的 CRUD 映射为:GET /vehicles/{id}/parts(读)、POST(建)、DELETE /vehicles/{id}/parts/{code}(删)、PUT(改)。
若你的 URI 像 /vehicles/listParts 或 /vehicles/getComboData,就违背了全球 API 惯例。API 开发者应始终用资源、子资源与查询参数来组织 URI,避免任何面向对象语言的命名风格。取某车零部件列表应写作 /vehicles/{vin}/parts;给下拉框加载数据可用 /vehicles/orders 或 /orders/vins。
服务演进时通常需要版本化。对外暴露给合作伙伴的 API,更新可能破坏客户端,因此发布全新版本是必要的。做法很简单:在 URI 中加入版本号,如 /api/v1/vehicles/ 是第一版;重构后用 /api/v2/vehicles/。建议用 OpenAPI 文档工具记录,既扩展服务又兼容老客户。但注意:若频繁出新版本(如已到第 5 版),说明设计阶段需要更审慎。
根据语言与框架,API 可返回 JSON、XML 或其他格式,但JSON 是 API 与 REST 服务的事实标准。返回 XML 并非不可,但需看业务规范;对公开接口,我们一律推荐 JSON。
并非所有接口都活在 200 的世界。认真做 API 设计,要为每种情况返回正确的 HTTP 状态码:
| 类别 | 状态码 | 含义 |
|---|---|---|
| 成功 | 200/201/202/204 | OK / 已创建 / 已接受 / 无内容 |
| 客户端错误 | 400/401/403/404/405/422/429 | 错误请求 / 未认证 / 禁止 / 未找到 / 方法不允许 / 语义错误 / 请求过多 |
| 服务端错误 | 500/502/503 | 内部错误 / 网关错误 / 服务不可用 |