REST API 设计的 15 个基本技巧

更新日期: 2023-04-20阅读: 842标签: api

REST api 是最常见的 Web 服务类型之一,但它们也很难设计。它们允许各种客户端(包括浏览器、桌面应用程序、移动应用程序以及基本上任何具有互联网连接的设备)与服务器进行通信。因此,正确设计 REST API 非常重要,这样我们就不会在以后遇到问题。

由于需要准备的东西太多,从头开始创建 API 可能会让人不知所措。从基本安全到使用正确的 HTTP 方法、实施身份验证、决定接受和返回哪些请求和响应等等。在这篇博文中,我尽我所能将一些关于什么是好的 API 的强有力的建议压缩到 15 个项目中。所有提示都与语言无关,因此它们可能适用于任何框架技术


1.确保在端点路径中使用名词

我们应该始终使用表示我们正在检索或操作的实体的名词作为路径名,并且始终支持使用复数名称。避免在端点路径中使用动词,因为我们的 HTTP 请求方法已经有了动词,并没有真正添加任何新信息。

该操作应由我们正在制作的 HTTP 请求方法指示。最常见的方法是 GET、POST、PATCH、PUT 和 DELETE。

  • GET 检索资源。
  • POST 向服务器提交新数据
  • PUT/PATCH 更新现有数据。
  • DELETE 删除数据。

动词映射到CRUD操作。

考虑到这些原则,我们应该创建像 GET 这样的路由/books来获取书籍列表,而不是 GET/get-books或 GET /book。同样,POST/books用于添加新书,PUT/books/:id用于更新给定的完整书籍数据id,而 PATCH/books/:id更新书籍的部分更改。最后,DELETE/books/:id用于删除具有给定 ID 的现有文章


2. JSON作为发送和接收数据的主要格式

几年前,接受和响应 API 请求主要是在 XML 中完成的。但如今,JSON(JavaScript 对象表示法)在很大程度上已成为大多数应用程序中发送和接收 API 数据的“标准”格式。因此,我们的第二项建议确保我们的端点返回 JSON 数据格式作为响应,并且在通过 HTTP 消息的有效负载接受信息时也是如此。

虽然Form Data很适合从客户端发送数据,尤其是当我们要发送文件时,但对于文本和数字来说并不理想。我们不需要表单数据来传输它们,因为对于大多数框架,我们可以直接在客户端传输 JSON。当从客户端接收数据时,我们需要确保客户端正确解释 JSON 数据,为此,在发出请求时应Content-Type将响应标头中的类型设置为。application/json

如果我们试图在客户端和服务器之间发送和接收文件,那么值得再次提及的异常。对于这种特殊情况,我们需要处理文件响应并将表单数据从客户端发送到服务器。


3.使用一组可预测的HTTP状态码

根据其定义使用HTTP 状态代码来指示请求的成功或失败始终是一个好主意。不要使用太多,并且在整个 API 中为相同的结果使用相同的状态代码。一些例子是:

  • 200为了普遍的成功
  • 201成功创作
  • 400对于来自客户端的错误请求,例如无效参数
  • 401对于未经授权的请求
  • 403缺少对资源的权限
  • 404缺少资源
  • 429对于太多的请求
  • 5xx对于内部错误(应尽可能避免)

根据您的用例,可能会有更多,但限制状态代码的数量有助于客户端使用更可预测的 API。


4.返回标准化消息

除了使用指示请求结果的 HTTP 状态代码之外,始终对类似端点使用标准化响应。消费者总是可以期待相同的结构并采取相应的行动。这也适用于成功,但也适用于错误消息。在获取集合的情况下,坚持使用特定格式,响应主体是否包含如下数据数组:

[
{
bookId: 1,
name: "The Republic"
},
{
bookId: 2,
name: "Animal Farm"
}
]

或这样的组合对象:

{
"data": [
{
"bookId": 1,
"name": "The Republic"
},
{
"bookId": 2,
"name": "Animal Farm"
}
],
"totalDocs": 200,
"nextPageId": 3
}

无论您为此选择哪种方法,建议都是一致的。在获取对象时以及在创建和更新资源时应该实现相同的行为,通常返回对象的最后一个实例是个好主意。

// Response after successfully calling POST /books
{
"bookId": 3,
"name": "Brave New World"
}

虽然这不会有什么坏处,但是包含一个像“Book successfully created”这样的通用消息是多余的,因为它是从 HTTP 状态代码中隐含的。

最后但并非最不重要的一点是,错误代码在具有标准响应格式时更为重要。此消息应包含消费者客户端可用于向最终用户显示错误的信息,而不是我们应尽可能避免的通用“出现错误”警报。这是一个例子:

{
"code": "book/not_found",
"message": "A book with the ID 6 could not be found"
}

同样,没有必要在响应内容中包含状态代码,但定义一组错误代码很有用,以便book/not_found消费者将它们映射到不同的字符串并为用户决定自己的错误消息。特别是对于开发/暂存环境,将错误堆栈也包含到响应中以帮助调试错误似乎就足够了。但请不要在生产环境中包含这些内容,因为它会产生暴露不可预测信息的安全风险。


5. 获取记录集合时使用分页、过滤和排序

一旦我们构建了一个返回项目列表的端点,就应该进行分页。集合通常会随着时间的推移而增长,因此始终返回有限且受控数量的元素非常重要。让 API 使用者选择要获取多少对象是公平的,但预定义一个数字并为其设置最大值始终是个好主意。这样做的主要原因是返回大量数据将非常耗费时间和带宽。

要实现分页,有两种众所周知的方法:skip/limit或keyset. 第一个选项允许以更用户友好的方式获取数据,但通常性能较低,因为数据库在获取“底线”记录时必须扫描许多文档。另一方面,我更喜欢的是,键集分页接收一个标识符/id 作为参考,以在不扫描记录的情况下“剪切”一个集合或表。

按照同样的思路,API 应该提供过滤器和排序功能,以丰富数据的获取方式。为了提高性能,数据库索引成为解决方案的一部分,以通过这些过滤器和排序选项应用的访问模式最大限度地提高性能。

作为 API 设计的一部分,分页、过滤和排序的这些属性被定义为URL 上的查询参数。例如,如果我们想要获得属于“浪漫”类别的前 10 本书,我们的端点将如下所示:

GET /books?limit=10&category=romance


6.PATCH代替PUT

我们不太可能需要一次完全更新完整的记录,通常会有敏感或复杂的数据,我们希望避免用户操作。考虑到这一点,PATCH应该使用请求来对资源执行部分更新,而不是PUT完全替换现有资源。两者都应使用请求body传递要更新的信息。仅在请求的情况下修改字段PATCH和请求的完整对象PUT。尽管如此,值得一提的是,没有什么能阻止我们使用PUT部分更新,没有“网络传输限制”可以验证这一点,这只是一个值得坚持的惯例。


7.提供扩展的响应选项

在创建可用的 API 资源和返回哪些数据时,访问模式是关键。当系统增长时,记录属性也会在该过程中增长,但并非所有这些属性始终是客户端操作所必需的。正是在这些情况下,提供为同一端点返回减少或完整响应的能力变得有用。如果消费者只需要一些基本字段,简化响应有助于减少带宽消耗,并可能降低获取其他计算字段的复杂性。

实现此功能的一种简单方法是提供额外的查询参数以启用/禁用扩展响应的提供。

GET /books/:id
{
"bookId": 1,
"name": "The Republic"
}
GET /books/:id?extended=true
{
"bookId": 1,
"name": "The Republic"
"tags": ["philosophy", "history", "Greece"],
"author": {
"id": 1,
"name": "Plato"
}
}


8.端点责任

单一职责原则侧重于保持函数、方法或类的概念,侧重于它擅长的狭义行为。当我们考虑一个给定的 API 时,如果它只做一件事并且永不改变,我们就可以说它是一个好的 API。这有助于消费者更好地理解我们的 API 并使其可预测,从而促进整体集成。最好将我们的可用端点列表扩展到更多,而不是构建试图同时解决许多问题的非常复杂的端点。


9.提供准确的API文档

API 的使用者应该能够理解如何使用可用端点以及对可用端点的期望。这只有在有良好而详细的文档的情况下才有可能。考虑以下几个方面以提供文档完善的 API。

  • 可用的端点描述它们的目的
  • 执行端点所需的权限
  • 调用和响应示例
  • 预期的错误消息

要取得成功的另一个重要部分是在系统更改和添加之后始终使文档保持最新。实现这一目标的最佳方法是使 API 文档成为开发的基本部分。这方面的两个著名工具是 Swagger 和 Postman,它们可用于大多数 API 开发框架。


10. 使用 SSL 确保安全并配置 CORS

安全性,我们的 API 应该具备的另一个基本属性。通过在服务器上安装有效证书来设置 SSL 将确保与消费者的安全通信并防止多种潜在攻击。

CORS(跨源资源共享)是一种浏览器安全功能,它限制从浏览器中运行的脚本发起的跨源 HTTP 请求。如果您的 REST API 的资源接收到非简单的跨源 HTTP 请求,您需要为消费者启用 CORS 支持以进行相应操作。

CORS 协议要求浏览器向服务器发送预检请求,并在发送实际请求之前等待服务器的批准(或凭证请求)。预检请求作为使用该方法(以及其他标头)的 HTTP 请求出现在 API 中OPTIONS。因此,为了支持 CORS,REST API 资源需要实现一种方法,该方法可以至少使用 Fetch 标准规定的以下响应标头来OPTIONS响应预检请求:OPTIONS

  • Access-Control-Allow-Methods
  • Access-Control-Allow-Headers
  • Access-Control-Allow-Origin

分配给这些键的值将取决于我们希望 API 的开放性和灵活性。我们可以分配特定的方法和已知的来源或使用通配符来开放 CORS 限制。


11. API版本

作为开发演变过程的一部分,端点开始改变并重建。但我们应该尽可能避免突然改变消费者的端点。将 API 视为向后兼容的资源是一个好主意,新的和更新的端点应该在不影响以前的标准的情况下可用。

这就是 API 版本控制变得有用的地方,客户端应该能够选择要连接的版本。有多种方法可以声明 API 版本控制:

1. Adding a new header "x-version=v2"
2. Having a query parameter "?apiVersion=2"
3. Making the version part of the URL: "/v2/books/:id"

详细了解哪种方法更方便,何时正式发布新版本以及何时弃用旧版本当然是要问的有趣问题,但不要过度扩展此项目,分析将是另一篇文章的一部分。


12.缓存数据以提高性能

为了提高我们 API 的性能,密切关注很少更改且经常访问的数据是有益的。对于这种类型的数据,我们可以考虑使用内存或缓存数据库,从而避免访问主数据库。这种方法的主要挑战是数据可能会过时,因此还应考虑采用最新版本的过程。

使用缓存数据对于消费者加载配置和信息目录非常有用,这些配置和目录不会随着时间的推移而改变。使用缓存时,请确保Cache-Control在标头中包含信息。这将帮助用户有效地使用缓存系统。


13.使用标准UTC日期

我想不出在某些时候不适用于日期的系统现实。在数据级别,重要的是在客户端应用程序的日期显示方式上保持一致。ISO 8601是日期和时间相关数据的国际标准格式。日期应为“Z”或 UTC 格式,客户可以根据该格式为其决定时区,以防在任何情况下需要显示此类日期。这是一个关于日期应该是什么样子的例子:

{
"createdAt": "2022-03-08T19:15:08Z"
}


14.健康检查端点

我们的 API 可能会在艰难时期出现故障,并且可能需要一些时间才能启动并运行它。在这种情况下,客户会希望知道服务不可用,以便他们了解情况并采取相应行动。为了实现这一点,提供一个端点(如GET /health)来确定 API 是否健康。这个端点可以被其他应用程序调用,例如负载平衡器。我们甚至可以更进一步,通知有关 API 部分的维护期或健康状况。


15.接受API密钥认证

允许通过 API 密钥进行身份验证为第三方应用程序提供了轻松创建与我们的 API 集成的能力。这些 API 密钥应使用自定义 HTTP 标头(例如Api-Key或X-Api-Key)传递。密钥应该有一个到期日期,并且必须可以撤销它们,以便出于安全原因使它们失效。

英文:https://medium.com/@liams_o/15-fundamental-tips-on-rest-api-design-9a05bcd42920


链接: https://fly63.com/article/detial/12444

浏览器中的图像识别 API

在 Native 开发中,Android 和 IOS 平台都在系统层面直接提供给了应用开发识别图像的一些能力,比如对于二维码/条形码的识别,Android 可以使用 barcode API 、 iOS 可以使用 CIQRCodeFeature API 。

JavaScript的API设计原则

Js的API设计原则总共包含了七个大块。系卤煮自己总结的一些经验和教训。本篇博文同时也参考了其他一些文章,相关地址会在后面贴出来。很难做到详尽充实,如果有好的建议或者不对的地方,还望不吝赐教斧正。

适合写api接口文档的管理工具有哪些?

现在越来越流行前后端分离开发,使用ajax交互。所以api接口文档就变的十分有意义了,目前市场有哪些比较优秀的接口文档管理工具呢?比如:MinDoc,eoLinker,apizza,RAML,Swagger等等

前后端分离,如何防止api接口被恶意调用或攻击

无论网站,还是App目前基本都是基于api接口模式的开发,那么api的安全就尤为重要了。目前攻击最常见的就是“短信轰炸机”,由于短信接口验证是App,网站检验用户手机号最真实的途径,使用短信验证码在提供便利的同时,也成了呗恶意攻击的对象,那么如何才能防止被恶意调用呢?

JSON API免费接口_ 免费的天气预报、地图、IP、手机信息查询、翻译、新闻等api接口

整理提供最新的各种免费JSON接口,其中有部分需要用JSONP调用。方面前端同学的学习或在网站中的使用,包括:免费的天气预报、地图、IP、手机信息查询、翻译、新闻等api接口

什么是RESTful API?

要弄清楚什么是RESTful API,首先要弄清楚什么是REST。REST -- REpresentational State Transfer,英语的直译就是“表现层状态转移”。如果看这个概念,估计没几个人能明白是什么意思。

认识 Fetch API

Fetch API 已经作为现代浏览器中异步网络请求的标准方法,其使用 Promise 作为基本构造要素。Fetch 在主流浏览器中都有很好的支持,除了IE。

用一个通俗的例子讲清楚API

随着移动互联网的发展, 基于互联网的应用正变得越来越普及,在这个过程中,更多的平台将自身的资源开放给开发者来调用。对外提供的API 调用使得平台之间的内容关联性更强,同时这些开放的平台也为用户、开发者和中小网站带来了更大的价值。

docker提供api访问

环境centos,添加deamon.json后,dockerd命令可以启动docker,这时请求 127.0.0.1:2375 可以正常访问,使用systemctl无法启动docker的情况.无法启动docker:查看当前的docker配置

构建API的最佳编程语言是什么?

你是否正在设计第一个Web应用程序?也许你过去已经建立了一些,但是目前也正在寻找语言的变化以提高你的技能,或尝试新的东西。有了所有信息,就很难决定为下一个产品或项目选择哪种编程语言。

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!