原文: REST API Best Practices – REST Endpoint Design Examples

在 Web 开发中,REST API 在确保客户端和服务器之间的顺利通信方面发挥了重要作用。

你可以把客户端看作是前端,把服务器看作是后端。

客户端(前端)和服务器(后端)之间的通信通常不是超级直接的。因此,我们使用一个叫作“应用编程接口”(或 API)的接口,作为客户端和服务器之间的中介。

因为 API 在这种客户端-服务器通信中起着至关重要的作用,所以我们在设计 API 时应该始终考虑到最佳实践。这有助于维护它们的开发人员和那些使用它们的人,在履行职责时不会遇到问题。

在这篇文章中,我将带你了解创建 REST API 时需要遵循的 9 个最佳实践。这将帮助你创建最好的 API,并使你的 API 用户使用起来更容易。

首先,什么是 REST API

REST 是Representational State Transfer 的缩写。它是由 Roy Fielding 在 2000 年创造的一种软件架构风格,用于指导网络的架构设计。

任何遵循 REST 设计原则的 API(应用编程接口)都被称为 RESTful。

简单地说,REST API 是两台计算机通过 HTTP(超文本传输协议)进行通信的媒介,与客户端和服务器的通信方式相同。

REST API 设计最佳实践

使用 JSON 作为发送和接收数据的格式

在过去,接受和响应 API 请求主要是通过 XML 甚至 HTML 完成的。但如今,JSON(JavaScript Object Notation)已经在很大程度上成为发送和接收 API 数据的事实格式。

这是因为,以 XML 为例,对数据进行解码和编码往往有点麻烦——所以 XML 不再受到框架的广泛支持。

例如,JavaScript 有一个内置的方法来通过 fetch API 解析 JSON 数据,因为 JSON 主要是为它而生成的。但是如果你使用任何其他编程语言,如 Python 或 PHP,它们现在也都有解析和操作 JSON 数据的方法。

例如,Python 提供 json.load()json.dumps() 来处理 JSON 数据。

为了确保客户端正确地解释 JSON 数据,你应该在发出请求时将响应头中的 Content-Type 类型设置为 application/json

另一方面,对于服务器端的框架,许多框架会自动设置 Content-Type。例如,Express 现在有 express.json() 中间件来实现这一目的。body-parser NPM 包也仍然适用于同一目的。

在端点中使用名词而不是动词

当你设计一个 REST API 时,你不应该在端点路径中使用动词。端点应该使用名词,表示它们各自的作用。

这是因为 HTTP 方法,例如 GETPOSTPUTPATCHDELETE,已经以动词形式执行基本的 CRUD(创建、读取、更新、删除)操作。

GETPOSTPUTPATCHDELETE 是最常见的 HTTP 动词。还有其他一些动词,如 COPYPURGELINKUNLINK 等等。

因此,举例来说,一个端点不应该是这样的:

https://mysite.com/getPosts or https://mysite.com/createPost

它应该是这样的: https://mysite.com/posts

简而言之,你应该让 HTTP 动词来处理端点的工作。因此,GET 将检索数据,POST 将创建数据,PUT 将更新数据,DELETE 将删除数据。

用复数名词命名集合

你可以把你的 API 的数据看成是来自用户的不同资源的集合。

如果你有一个像 https://mysite.com/post/123 这样的端点,用 DELETE 请求删除一个帖子,或用 PUTPATCH 请求更新一个帖子,可能是可以的,但它没有告诉用户在这个集合中可能还有一些其他的帖子。这就是为什么你的集合应该使用复数的名词。

所以,不应该是 https://mysite.com/post/123,而是 https://mysite.com/posts/123

在错误处理中使用状态码

你应该在对你的 API 请求的响应中始终使用常规的 HTTP 状态代码。这将帮助你的用户知道发生了什么——请求是否成功,或者是否失败,或者其他情况。

下面的表格显示了不同的 HTTP 状态代码范围和它们的含义:

状态码范围 含义
100 – 199 信息性回应:例如,102 表示该资源正在处理中
300 – 399 重定向:例如,301 表示永久移动
400 – 499 客户端错误:400 表示错误的请求,404 表示未找到资源
500 – 599 服务器端错误:例如,500 表示内部服务器错误

在端点上使用嵌套来显示关系

很多时候,不同的端点可以相互联系,所以你应该对它们进行嵌套,这样更容易理解它们。

例如,对于一个多用户博客平台,不同的帖子可能是由不同的作者写的,所以在这种情况下,像 https://mysite.com/posts/author 这样的端点会成为一个有效的嵌套。

同样地,帖子可能有各自的评论,所以要检索评论,可以使用 https://mysite.com/posts/postId/comments 这样的端点。

你应该避免超过 3 层的嵌套,因为这可能使 API 不那么优雅和具有可读性。

使用过滤、排序和分页来检索请求的数据

有时,API 的数据库可能非常大。如果发生这种情况,从这样的数据库中检索数据可能非常缓慢。

过滤、排序和分页都是可以在 REST API 的集合上执行的操作。这样只能检索、排序和排列必要的数据,并将其分页,以防服务器请求过载。

以下是一个已过滤的端点的示例:https://mysite.com/posts?tags=javascript。此端点将检索具有 JavaScript 标签的任何帖子。

使用 SSL 保障安全

SSL 指的是安全套接层。这对于 REST API 设计的安全性至关重要。这将保护你的 API,使其更不容易受到恶意攻击。

你还应考虑其他安全措施,包括:使服务器和客户端之间的通信保密,确保使用 API 的任何人不会获得他们请求的以外的数据。

SSL 证书不难加载到服务器上,而且大多数情况下在第一年是免费的。即使需要购买,它们也并不昂贵。

运行在 SSL 上的 REST API 的 URL 与不运行在 SSL 上的 URL 的明显区别是 HTTP 中的 “s”:https://mysite.com/posts 运行在 SSL 上,http://mysite.com/posts 不运行在 SSL 上。

明确版本划分

REST API 应该有不同的版本,所以你不会强迫客户(用户)迁移到新版本。如果你不小心,这甚至可能破坏应用程序。

网络开发中最常见的版本控制系统之一是语义版本控制。

语义版本管理的一个例子是 1.0.0、2.1.2 和 3.3.4。第一个数字代表主要版本,第二个数字代表次要版本,第三个数字代表补丁版本。

许多科技巨头和个人的 RESTful API 通常是这样的:https://mysite.com/v1/ 代表版本 1,https://mysite.com/v2 代表版本 2。

Facebook 的 API 版本是这样的:

facebook-versioning

Spotify 以同样的方式做他们的版本管理:

spotify-versioning

并不是每个 API 都是这样的情况。Mailchimp 的 API 版本是这样的:

mailchimp-ersioning

当你以这种方式创建 REST API 时,你不强制客户端在选择不迁移的情况下迁移到新版本。

提供准确的 API 文档

当你创建 REST API 时,你需要帮助用户(消费者)正确学习并了解如何使用它。最好的方法是为 API 提供良好的文档。

文档应包含:

  • API 的相关端点
  • 端点的示例请求
  • 在几种编程语言中的实现
  • 不同错误的消息列表及其状态代码

你可以用于 API 文档的最常用工具是 Swagger。你也可以使用 Postman 来记录你的 API,这是软件开发中最常见的 API 测试工具。

总结

在这篇文章中,你了解了在创建 REST API 时需要记住的几个最佳实践。

将这些最佳实践和惯例付诸实践是很重要的,这样你就可以创建功能强大的应用程序,使其运行良好、安全,并最终使你的 API 用户能够更加容易地使用它。

谢谢你阅读本文。现在,去用这些最佳实践创建一些 API 吧。