RESTful API 设计指南——最佳实践

10年服务1亿前端开发工程师

Facebook、谷歌、Github、Netflix 和几个其他的科技巨头已经允许开发者和其产品通过 API 调用他们的数据,并为他们提供平台。即使你不是写 API 的专业人士,拥有精美的 API 也对你的应用程序有好处。

关于设计 API 的最好方法,网络上有较长一段时间的争论,但官方也没有对此给出解释。

API 是一个接口,通过它许多开发者可与数据交互。 设计优良的 API 使用起来很方便,并给开发者的工作带来便利。 API 是开发者的 GUI,如果它设计不合理,开发者会将它替换。所以,开发者的经验是衡量 API 质量的最重要的指标。

API就像一个在舞台上表演的艺术家,其用户就是其观众

1) 术语

以下是与 REST API 相关的重要术语:

  • 资源(Resource) 是一个对象或对某物的表示。它有一些相关联的数据,并有一组方法进行操作。 例如:动物,学校和员工是资源。这些资源都有着删除,添加,更新操作。
  • 集合(Collection)是一系列资源,例如:公司集合是很多公司的集合。
  • URL(统一资源定位符)是一种路径,可以通过它定位资源并且也可以对它执行一些动作。

2) API 端点(路径)

为了更好理解,我们给公司写 API,这些公司都有一些员工。/getAllEmployees 是对员工列表进行回应的 API。公司其他 API 大致如下:

  • /addNewEmployee
  • /updateEmployee
  • /deleteEmployee
  • /deleteAllEmployees
  • /promoteEmployee
  • /promoteAllEmployees

并且将有大量的和这些操作不同的 API 端点,它们包含大量冗余的行为。因此,当 API 数量增加时,这些 API 端点将很难维护。

哪里不对?

每个 URL 代表一种资源(Resource),所以 URL 中只能有名词,不能有动词。 API 路径 /addNewEmployee 包含了操作 addNew 和资源名称?Employee。

那么怎样算是正确的方式?

/companies 是一个很好的不包含操作的例子。但是问题来了,我们该怎样告诉服务器我们要进行的操作呢?新增,删除,还是更新?

这时?HTTP 方法(GET,POST,DELETE,PUT)(也称为动词)就可以起到作用了。

资源在 API 端点中应该总是复数,如果我们想访问资源的一个实例,我们可以传递 URL 中的 id。

  • 方法 GET 路径 /companies 是获取所有公司的列表。
  • 方法 GET?路径 /companies/34 是获取公司34的详细信息。
  • 方法 DELETE?路径 /companies/34 是删除公司34.

在其他的一些使用案例中,如果我们有一些资源在某个资源之下,例如,一个公司的员工,那么在这样的例子中 API 的 endpoint(端点) 就应该是这样的:

  • GET /companies/3/employees 可以取得编号为3的公司的员工列表
  • GET /companies/3/employees/45?可以取得编号为3的公司的45号员工的细节信息
  • DELETE /companies/3/employees/45 可以删除编号为3的公司的45号员工
  • POST /companies 可以创建一个新公司并返回新创建公司的细节信息

现在这样,API 是不是更严谨和一致了呢?

结论:路径应该包含资源的复数形式,HTTP 方法应该定义成各种行为在资源上执行。

3) HTTP 方法 (动词)

HTTP 定义了几组方法,这些方法给出了对资源要执行的操作类型。

URL 是一个句子,其中资源是名词,HTTP 方法是动词。

主要的HTTP方法如下:

  1. GET 方法从资源请求数据,不产生多余结果。
    例如: /companies/3/employees 会返回公司3的所有雇员列表。
  2. POST 方法请求服务器在数据库中创建资源,这主要用于提交 Web 表单时。
    例如: /companies/3/employees 创建一个公司3的新雇员。
    POST 是非幂等的,这意味着多个请求将会有不同的效果。
  3. PUT 方法请求服务器更新资源或创建资源(如果不存在的话)。
    例如: /companies/3/employees/john 将请求服务器在公司3的雇员集合中更新或在不存在的情况下创建关于 john 的资源。
    PUT 是幂等的,这意味着多次请求具有相同的效果。
  4. DELETE 方法将请求的资源或实例从数据库中删除。
    例如: /companies/3/employees/john/ 将请求服务器从公司3的雇员集中删除 john 资源。

HTTP 中还有很多其他方法,我们将在另一篇文章中讨论。

4) HTTP 响应状态码

当客户端通过 API 向服务器发起请求时,无论请求是失败的、通过的还是错误的,客户端应该获得反馈。HTTP 状态码是一堆标准化的数值码,在不同的情况下具有不同的解释。服务器应始终返回正确的状态码。

以下是 HTTP 状态码的主要分类:

2xx (成功类别)

这些状态代码表示请求的操作已被服务器接收到并成功处理。

  • 200 Ok:标准的 HTTP 响应,表示 GET、PUT 或 POST 的处理成功。
  • 201 Created:在创建新实例时,应返回此状态代码。例如,使用 POST 方法创建一个新的实例,应该始终返回 201 状态码。
  • 204 内容不存在:表示请求已被成功处理,但并未返回任何内容。

DELETE算是其中一个很好的例子。

API DELETE /companies/43/employees/2?将删除员工 2,作为响应,我们不需要在该 API 的响应正文中的任何数据,因为我们明确地要求系统将其删除。如果有任何错误发生,例如,如果员工 2 在数据库中不存在,那么响应码将不是 2xx 对应的成功类别,而是 4xx 客户端错误类别。

3xx (重定向类别)

  • 304 未修改:表示客户端的响应已经在其缓存中。 因此,不需要再次传送相同的数据。

4xx (客户端错误类别)

这些状态代码表示客户端发起了错误的请求。

  • 400 错误请求:表示客户端的请求没有被处理,因为服务器不能理解客户端请求的是什么。
  • 401 未授权:表示客户端不被允许访问该资源,需要使用指定凭证重新请求。
  • 403 禁止访问:表示请求是有效的并且客户端已通过身份验证,但客户端不被允许以任何理由访问对应页面或资源。 例如有时授权的客户端不被允许访问服务器上的目录。
  • 404 未找到:表示所请求的资源现在不可用。
  • 410 资源不可用:表示所请求的资源后续不再可用,该资源已被移动。

5xx(服务器错误类别)

  • 500是服务器内部错误,表示请求已经被接收到了,但服务器被要求处理某些未预设的请求而完全混乱。
  • 503服务不可用表示服务器已关闭或无法接收和处理请求。大多数情况是服务器正在进行维护。

5) 字段套管约定

您可以遵循任何套管约定,但要确保其在应用程序中一致。如果请求主体或响应类型是JSON,那么请按照camelCase(驼峰命名法)来保持一致。

6) 搜索、排序、过滤和分页

这些行为都只是针对一个数据集进行的查询。由于还没有一套新的 API 来处理这些行为。因此,我们需要向 GET 方法的 API 附加查询参数。

我们来理解几个例子看它们是如何实现这些行为的。

  • 排序(sorting),客户端想要获得排序后的公司列表,GET /companies 端点应当接受多个查询排序参数。
    例如,GET /companies?sort=rank_asc 将根据等级以升序的方式对公司进行排序。
  • 过滤(Filtering),用来过滤数据集,我们可以通过查询参数传递不同的选项。
    例如,GET /companies?category=banking&location=india 将根据公司类别为银行以及所处位置为印度来过滤公司的列表数据。
  • 搜索(Searching),当需要在公司列表中搜索公司名称时,API 端点应当是 GET /companies?search=Digital Mckinsey。
  • 分页(Pagination),当数据集太大时,我们将数据集分成更小的块,这样有助于提高性能,并且更易于处理响应。 例如,GET /companies?page=23 表示获取第 23 页的公司列表。

如果在 GET 方法中附加了很多查询参数,会造成 URI 太长,服务器可能会响应 414 的 HTTP 状态,表示这个 URI 太长,在这种情况下,我们也可以将参数传递给 POST 方法的请求体中。

7) 版本控制

当你的 API 被开始被广泛使用后,突然升级API会打破现有的产品、服务。

http://api.yourservice.com/v1/companies/34/employees?是一个很好的例子,它的路径中有API的版本号。如果有任何重大的中断更新,我们可以将新的API集命名为v2或v1.x.x

这些指南是根据我的开发经验编写的。我很想知道你对上述几点的看法。

赞(2)
未经允许不得转载:前端精选 » RESTful API 设计指南——最佳实践

评论 1

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

前端开发相关广告投放 更专业 更精准

联系我们