精通 RESTful API 设计:实用指南
RESTful API(表述性状态转移 API)是一种用于网络应用程序之间交互的网络接口设计风格。REST 是一套架构原则和约束,而非标准或协议。当一个 Web 服务符合 RESTful 规范时,它遵循 REST 原则,并提供高效、可靠且可扩展的网络服务。
在 RESTful 服务中,每个请求都应该包含处理该请求所需的所有信息。服务器不应该保留任何关于客户端请求的状态信息。
RESTful 架构可能包含多个层,每一层都执行特定的功能。这种结构允许开发更复杂、更强大的应用程序。
URI 设计
在 RESTful API 设计中,URL(统一资源定位符)通常代表资源(对象),而 HTTP 方法(例如 GET、POST、PUT、DELETE 等)则代表对这些资源的操作(动词)。这种设计风格强调资源的状态和表示,而非操作本身。
动词 + 宾语
RESTful API 中的动词通常是五个 HTTP 方法,分别对应于 CRUD 操作:
- 获取:读取
- 帖子:创建
- PUT:更新
- 补丁:更新(通常用于部分更新)
- 删除:删除
根据HTTP规范,动词必须始终大写。
该对象必须是名词
在设计 API 时,URL(统一资源定位符)通常代表一个资源,该资源作为 HTTP 动词的对象。根据 RESTful 设计原则,URL 应该是名词而不是动词,因为它们代表的是“资源”集合或单个实例,而不是一个操作。
错误示例:
/getAllCars/createNewCar/deleteAllRedCars
这些 URL 包含动词(例如 get、create、delete),描述的是操作而非资源本身。这种设计不符合 RESTful 语义标准。
正确方法:
URL 应侧重于描述资源,而非操作。以下是符合规范的 URL 设计示例:
/users:表示一组用户/users/123:代表具有特定 ID (123) 的单个用户
在上述示例中,` users`/users和/users/123`userresource` 均为名词,分别代表用户集合和特定用户资源。这种 URL 设计使 API 更易于理解,并符合 RESTful 资源导向原则。
通过遵循这种命名约定,我们可以确保 API 路径清晰、一致且易于理解和维护。
复数网址
为了保持一致性和清晰度,通常建议在 URL 中使用复数形式,因为 URL 通常代表资源的集合。
当您的 URL 指向资源集合时,请使用复数名词。例如,使用 `users`/users而不是 `users`/user来表示所有用户的集合。
即使指向单个资源,也建议使用复数形式。例如,` /users/123user123` 表示 ID 为 123 的用户。这种方法可以保持 URL 的一致性。
当资源具有层级关系时,URL 应反映这种结构。例如,/users/123/posts可以表示用户 123 的帖子集合。
避免使用深度嵌套的URL
常见的情况是,当资源需要多级分类时,就会产生嵌套很深的 URL,例如检索特定作者的特定类别的文章:
GET /authors/12/categories/2
此类 URL 难以扩展,且语义不明确,通常需要额外努力才能理解。更好的方法是在第一级 URL 之外使用查询参数:
GET /authors/12?categories=2
另一个例子是查询已发表的文章。您可以这样设计 URL:
GET /articles/published
然而,使用查询参数显然是更好的方法:
GET /articles?published=true
状态码
状态码必须精确
服务器必须对每个客户端请求返回 HTTP 状态码和数据。
HTTP 状态码是一个三位数,分为五类:
- 1xx:信息
- 2xx:成功
- 3xx:重定向
- 4xx:客户端错误
- 5xx:服务器错误
这五大类状态码包含超过 100 个,涵盖了大多数可能的情况。每个状态码都有一个标准(或约定俗成)的含义,客户端只需检查状态码即可确定发生了什么。因此,服务器应该返回尽可能精确的状态码。
API 不需要1xx状态码。以下是对其他四类状态码的解释。
2xx 状态码
不同的HTTP请求方法应返回相应的状态码以指示请求结果。虽然200 OK是通用的成功响应,但应根据具体方法使用更精确的状态码:
- GET: 200 OK – 请求成功,资源已返回。
- POST: 201 Created – 已成功创建新资源,响应通常包含资源的 URI。
- PUT:200 OK 或 204 No Content – 用于完整资源更新。如果返回内容,则使用200;否则,使用204。
- PATCH:返回 200 OK 或 204 No Content –用于部分更新,类似于 PUT 请求。204表示未返回任何内容。
- 删除:204 无内容– 表示资源已成功删除,响应中通常没有内容。
- 202 Accepted – 请求已被接受但尚未处理,适用于异步操作。
- 206 部分内容– 表示部分响应,通常用于客户端使用Range标头请求大文件的一部分时。
3xx 状态码
API 通常不使用301(永久重定向)或302(临时重定向,包括 307),因为它们主要用于浏览器级别的导航。API 可以在应用程序级别处理此类情况。
然而,API 可能会使用303 See Other重定向,指向另一个 URL。与302和307类似,303 也表示“临时重定向”,但303专门用于POST、PUT 和 DELETE请求。与302不同的是,浏览器不会自动执行303重定向,而是允许用户决定下一步操作。
示例回复:
HTTP/1.1 303 See Other
Location: /api/orders/12345
4xx 状态码
4xx状态码表示客户端错误。常见错误包括:
- 400 错误请求– 服务器无法理解客户端的请求,因此不予处理。
- 401 未授权– 用户未提供身份验证凭据或身份验证失败。
- 403 禁止访问– 用户已成功通过身份验证,但没有访问资源的权限。
- 404 未找到– 请求的资源不存在或不可用。
- 405 方法不允许– 用户已成功通过身份验证,但正在使用不允许的 HTTP 方法。
- 410 已移除– 请求的资源已被永久移除。
- 415 不支持的媒体类型– 请求的格式不受支持。例如,如果 API 只返回 JSON,但客户端请求 XML,则应返回此状态码。
- 422 无法处理的实体– 客户端提供的附件无法处理,导致请求失败。
- 429 请求过多– 客户端已超出允许的请求数量。
5xx 状态码
5xx状态码表示服务器错误。API 通常不会向用户暴露内部服务器详细信息,因此通常只使用两种状态码:
- 500 内部服务器错误– 客户端请求有效,但服务器在处理该请求时遇到了意外问题。
- 503 服务不可用– 服务器暂时无法处理请求,通常在维护期间使用。
服务器响应
不要返回纯文本
API 响应不应是纯文本,而应是结构化的 JSON 对象,以确保格式标准化。服务器的Content-Type标头应设置为application/json。
客户端还应在其请求中设置Accept标头,以表明它接受 JSON 响应:
GET /orders/2 HTTP/1.1
Accept: application/json
不要返回错误状态码 200
错误的做法是始终返回200 OK,即使发生错误,并将错误详情包含在响应体中。这会迫使客户端解析响应体来判断请求是否失败,从而违背了状态码的初衷。
反例:
HTTP/1.1 200 OK
Content-Type: application/json
{
"status": "failure",
"data": {
"error": "Expected at least two items in list."
}
}
在这种情况下,请求失败,但服务器仍然返回了200 OK。客户端必须检查"status": "failure"响应体中的字段才能检测到错误。这种方法不符合 RESTful 原则,并且使错误处理更加复杂且更容易出错。
正确示例:
状态码应指示请求结果。错误应使用相应的状态码进行传达,而响应正文则提供更多详细信息。
例如,如果请求无效,服务器应返回400 Bad Request错误,并以 JSON 格式提供错误详情:
HTTP/1.1 400 Bad Request
Content-Type: application/json
{
"error": "Invalid payload.",
"detail": {
"surname": "This field is required."
}
}
这里,400明确表示请求无效,而响应正文提供了具体的错误详情,以帮助客户端了解问题所在。
提供链接
在 RESTful API 中,在响应中包含链接是一种常见做法。这遵循了“超媒体作为应用程序状态引擎”(HATEOAS)原则,该原则增强了 API 的可发现性和自描述性。
以下是两种常见的添加链接的方式:
使用 HAL(超文本应用语言)
HAL 是一种流行的超媒体格式,用于表示资源之间的关系。它使用JSON 响应中的_links字段:
{
"id": 1,
"name": "Example",
"_links": {
"self": {
"href": "http://api.example.com/resource/1"
},
"related": {
"href": "http://api.example.com/resource/2"
}
}
}
直接在 JSON 中嵌入链接
{
"id": 1,
"name": "Example",
"links": {
"self": "http://api.example.com/resource/1",
"related": "http://api.example.com/resource/2"
}
}
内容退货政策
在 RESTful API 设计中,使用POST请求来创建新资源。响应是否应包含新创建的资源取决于具体的实现需求。有两种常见的做法:
1. 返回已创建的资源
这种方法包含一个201 Created状态码,并在响应中包含新资源的完整详细信息。它还包含一个指向资源 URI 的Location标头。
HTTP/1.1 201 Created
Location: /resources/123
Content-Type: application/json
{
"id": 123,
"name": "New Resource"
}
2. 请勿退回内容
或者,服务器可以选择仅返回带有Location标头的201 Created或204 No Content响应,省略资源详细信息。这样可以最大限度地减少数据传输,并让客户端决定是否稍后检索资源。
HTTP/1.1 201 Created
Location: /resources/123
结论
RESTful API 遵循HTTP 协议,强调资源表示和无状态交互。通过使用标准的 HTTP 方法(GET、POST、PUT、DELETE)和精确的状态码,RESTful 架构为构建网络应用程序提供了一种简单、高效且易于维护的方式。这种方法增强了Web 服务的可扩展性、灵活性和可维护性。
我们是 Leapcell,您托管后端项目的首选。
Leapcell是面向 Web 托管、异步任务和 Redis 的下一代无服务器平台:
多语言支持
- 使用Node.js、Python、Go或Rust进行开发。
免费部署无限量项目
- 仅需为使用量付费——不接受任何请求,不收取任何费用。
无与伦比的成本效益
- 按需付费,无闲置费用。
- 例如:25 美元支持 694 万次请求,平均响应时间为 60 毫秒。
简化的开发者体验
- 直观的用户界面,轻松完成设置。
- 全自动 CI/CD 流水线和 GitOps 集成。
- 实时指标和日志记录,以获取可操作的见解。
轻松扩展和高性能
- 自动扩缩容,轻松应对高并发情况。
- 零运营成本——只需专注于建设。
更多信息请参阅文档!
请在 X 上关注我们:@LeapcellHQ
文章来源:https://dev.to/leapcell/mastering-restful-api-design-a-practical-guide-408


