掌握 RESTful API 设计:实用指南

117 阅读10分钟

覆盖

RESTful API(表述性状态转移 API)是一种用于网络应用程序之间交互的网络接口设计样式。REST 是一组架构原则和约束,而不是标准或协议。当 Web 服务是“RESTful”时,它会遵循 REST 原则并提供高效、可靠且可扩展的网络服务。

在 RESTful 服务中,每个请求都应包含处理该请求所需的所有必要信息。服务器不应保留有关客户端请求的任何状态信息。

RESTful 架构可能由多个层组成,每个层执行特定功能。此结构允许开发更复杂、更强大的应用程序。

URI 设计

在 RESTful API 设计中,URL(统一资源定位符)通常表示资源(对象),而 HTTP 方法(如 GET、POST、PUT、DELETE 等)表示对这些资源的操作(动词)。这种设计风格强调资源的状态和表示,而不是动作。

动词 + 宾语

RESTful API 中的动词通常是五种 HTTP 方法,对应 CRUD 操作:

  • 获取:读取
  • POST : 创建
  • PUT:更新
  • PATCH:更新(通常为部分更新)
  • 删除:删除

根据 HTTP 规范,动词应该始终大写。

宾语必须是名词

在设计 API 时,URL(统一资源定位符)通常表示作为 HTTP 动词对象的资源。根据 RESTful 设计原则,URL 应该是名词而不是动词,因为它们表示的是“资源”集合或单个实例,而不是动作。

错误示例:

  • /getAllCars
  • /createNewCar
  • /deleteAllRedCars

这些 URL 中包含动词(如 get、create、delete),描述的是操作而不是资源本身。这种设计不符合 RESTful 语义标准。

正确做法:

URL 应侧重于描述资源而不是操作。以下是合规 URL 设计的示例:

  • /users:代表用户集合
  • /users/123:代表具有特定 ID 的单个用户(123)

上面的例子中,/users/users/123都是名词,分别代表用户集合和具体的用户资源。这样的 URL 设计让 API 更加容易理解,也更符合 RESTful 面向资源的原则。

通过遵循此命名约定,我们确保 API 路径清晰、一致且易于理解和维护。

复数 URL

通常建议在 URL 中使用复数形式以保持一致性和清晰度,因为它们通常代表资源集合。

当您的 URL 指向资源集合时,请使用复数名词。例如,使用/users而不是/user来表示所有用户的集合。

即使指向单个资源,也建议使用复数形式。例如,/users/123表示 ID 为 123 的用户。此方法可保持 URL 一致性。

当资源具有层次关系时,URL 应该反映这种结构。例如,/users/123/posts可以表示用户 123 的帖子集合。

避免深度嵌套的 URL

一种常见的情况是,当资源需要多级分类时,会导致 URL 嵌套很深,比如检索特定作者的某一类别的文章:

GET /authors/12/categories/2

此类 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 已创建– 已成功创建新资源,并且响应通常包含资源的 URI。
  • PUT:200 OK 或 204 No Content – 用于完整资源更新。如果返回内容,则使用200;如果没有,则使用204
  • PATCH:200 OK 或 204 No Content – 用于部分更新,类似于 PUT。204表示未返回内容。
  • DELETE:204 无内容– 表示资源已成功删除,通常响应中没有内容。
  • 202 已接受– 请求已被接受但尚未处理,对于异步操作很有用。
  • 206 部分内容– 表示部分响应,通常用于客户端使用 Range标头请求大文件的一部分时。

3xx 状态代码

API 通常不使用301(永久重定向)302(临时重定向,包括 307), 因为它们主要与浏览器级导航相关。API 可以在应用程序级别处理此类场景。

但是,API 可能会使用303 See Other,它引用另一个 URL。与302307一样,它表示“临时重定向”,但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 Gone–**请求的资源已被永久删除。
  • 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 Created204 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 集成。
  • 实时指标和日志记录可提供可操作的见解。

轻松实现可扩展性和高性能

  • 自动扩展以轻松处理高并发。
  • 零运营开销——只需专注于建设。

【智答专家】您身边免费的GPT4.0人工智能Ai助手,免翻!!!无套路!国内直连,支持文本生成、问答、多语言支持、个性化建议、图片生成、代码纠正等等。访问链接