首页 » 网站建设 » phpjirasoapapi技巧_开拓者若何才能写出好的 API

phpjirasoapapi技巧_开拓者若何才能写出好的 API

访客 2024-12-13 0

扫一扫用手机浏览

文章目录 [+]

现在,每个人都在关注 API。
API 最早开始盛行于大约 20 年前,2000 年,Roy Fielding 在他的博士论文中首次提出了 REST 这个术语。
同年,Amazon、Salesforce 和 eBay 向全天下的开拓者先容了他们的 API,永久改变了我们构建软件的办法。

在 REST 之前,Roy Fielding 论文中的原则被称为“HTTP 工具模型”,随后你会明白这为何非常主要。

phpjirasoapapi技巧_开拓者若何才能写出好的 API

随着阅读的深入,你还会看到如何确定你的 API 是否成熟,好 API 的紧张品质是什么以及为何在构建 API 的时候,要看重适应性。

phpjirasoapapi技巧_开拓者若何才能写出好的 API
(图片来自网络侵删)
RESTful 架构根本

REST 代表表述性状态转移(Representational State Transfer),由 Roy Fielding 在他的博士论文中定义,长期以来,它便是做事 API 的圣杯。
它并不是构建 API 的唯一办法,但是由于它的盛行,即便是非开拓职员也知道这种标准。

RESTful 软件有如下六种特点:

客户端-做事器端架构无状态可缓存分层系统按需编码(可选)统一接口

但是,对日常利用来说,这过于理论化了。
我们须要更具操作性的东西,这也便是 API 成熟度模型。

Richardson 成熟度模型

该模型是由 Leonard Richardson 提出的,它将 RESTful 开拓原则结合成四个大略易行的步骤。

在模型中的位置越高,就越靠近 Roy Fielding 所定义的 RESTful 原始理念。

Level 0:POX(Plain Old XML)的泥沼

Level 0 的 API 是一组大略 XML 或 JSON 的描述。
在前文中,我曾经说过在 Fielding 的论文之前,RESTful 原则被称为“HTTP 工具模型”。

这是由于 HTTP 是 RESTful 开拓中最主要的组成部分。
REST 要尽可能多地利用 HTTP 固有属性中的理念。

在 Level 0,没有利用任何这样的东西。
我们只是构建自己的协议并把它作为一个专有层。
这种架构被称为远程过程调用(Remote Procedure Call,RPC),适用于远程过程/命令。

常日我们会有一个端点,可以对它进行调用以获取一堆 XML。
在这方面,一个范例的例子便是 SOAP 协议:

其余一个很好的例子便是 Slack API。
它有些多样化,有多个端点,但依然是 RPC 风格的 API。
它暴露了 Slack 的各种功能,中间没有附加任何特性。
如下的代码展示了如何向一个特定的通道发送:

虽然按照 Richardson 的模型,这是一个 Level 0 的 API,但是这并不虞味着它是不好的。
只要它是可用的,并且恰当地做事于业务需求,那它便是很棒的 API。

Level 1:资源

为了构建 Level 1 的 API,我们须要找出系统中的名词并将它们通过不同的 URL 暴露出来,如下面的样例所示:

个中,“/api/books”能让我访问一个通用的图书目录,“/api/profile”能够让我访问这些书的作者的基本信息。
为了获取某个资源的第一个特定实例,我可以在 URL 中添加 ID(或其他引用)。

在 URL 中还可以嵌套资源,这展示了它们因此层级构造的形式组织的。

回到 Slack 的样例,如下展示了按照 Level 1 API,它们会是什么样子的:

现在,URL 发生了变革,从原来的“/api/chat.postMessage”变成了现在的“/api/channels/general/messages”。

信息中“channel”部分从要求体转移到了 URL 中。
从字面就能看出,通过利用这个 URL,我们可以预期有条发布到了“general”通道上。

Level 2:HTTP 动作

Level 2 利用 HTTP 动作(verb)来添加更多的含义和意图。
在这方面可用的动作比较多,我这里只用到一个根本的子集:PUT / DELETE / GET / POST。

借助这些动作,我们可以预期包含它们的 URL 有不同的行为:

POST:创建新数据PUT:更新现有的数据DELETE:移除数据GET:查找特定 id 的数据输出,获取某个资源(或全体凑集)

以上面提到的“/api/books”为例:

那这里的“安全”和“幂等”又是什么意思呢?

“安全”的方法指的是永久不会改变数据的方法。
REST 建议 GET 方法只能用来获取数据,以是在上面的凑集中,它是唯一一个安全的方法。
不管你调用多少次基于 REST 的 GET 方法,它永久不会改变数据库中的任何东西。
但是,这并不是该动作的固有特性,而是关系到你该如何实现它,以是我们须要确保它是这样运行的。
所有其他的方法都会以不同的办法改变数据,不能随意利用。
在 REST 中,GET 方法既是安全的,又是幂等的。

“幂等”的方法指的是多次利用不会产生不同结果的方法。
按照 REST,DELETE 方法该当是幂等的,如果删除了某个资源,然后针对相同的资源再次调用 DELETE,它不会改变任何东西。
资源该当早就已经消逝了。
在 REST 规范中,POST 是唯一一个非幂等的方法,以是我们可以对相同的资源多次调用 POST 方法,这样我们会得到重复的资源。

我们重新看一下 Slack 样例,如果我们利用 HTTP 动作来进行更多的操作会是什么样子:

我们可以利用 POST 方法发送到通用的通道,我们也可以利用 GET 方法从通用通道获取消息。
我们还可以利用 DELETE 方法和特定的 ID 删除,这里比较故意思的一点在于,并不是与特定通道关联的,以是我可以设计一个单独的 API 来删除资源。
这个例子表明,设计 API 并不总是那么大略,这方面有很多可选项和权衡。

Level 3:HATEOAS

还记得纯笔墨、没有任何图像的电脑游戏吗?我们只能看到一些文本,描述了你在哪里,以及接下来能干什么。
为了取得进展,我们必须要输入自己的选择。
在一定程度上来讲,HATEOAS 便是做这件事情的。

HATEOAS 指的是“超媒体作为运用状态引擎(Hypermedia as the Engine of Application State)”。

有了 HATEOAS 之后,当其他人利用你的 API 的时候,他们就能看到通过 API 还能做哪些其他的事情。
HATEOAS 回答了“从这里出发,我还能去哪里?”的问题。

但这还不是所有的内容。
HATEOAS 还可以对数据关系进行建模。
我们可能会有一个关于图书的资源,并且在 URL 中没有将作者信息嵌套进来,但是我们可以包含它们的链接,如果有人对作者感兴趣的话,那么他们可以访问这些链接并探索干系的数据。

HATEOAS 不像其他成熟度模型的等级那样盛行,但是有些开拓职员确实在利用它。
个中一个样例便是 Jira,如下是它们的搜索 API 的相应:

他们将链接嵌入到了其他我们可以探索的资源中,以及该 issue 的状态过渡列表。

其余一个利用 HATEOAS 的样例是 Artsy。
他们的 API 严重依赖 HATEOAS,并且还利用了 JSON Plus 调用规范,按照该规范逼迫哀求利用一种分外的约定来构建链接。
下面是一个分页的例子,这是利用 HATEOAS 最酷的样例之一:

我们可以供应到下一页、上一页、第一页和末了一页的链接,还可以按照须要添加其他页面的链接。
这样简化了 API 的消费,由于这样不须要在客户端添加 URL 的解析逻辑,也不须要追加页码的方法。
我们只须要在客户端利用已经实现构造化的链接就可以了。

好的 API 由什么组成

我们已经先容完了 Richardson 模型,但这并不是实现好的 API 的全部内容。
其他主要的品质还有什么呢?

缺点/非常处理

我对自己利用的 API 的基本期望之一便是,须要有一种明确的办法来判断是否有缺点或非常。
我想要知道要求是否得到了处理。

HTTP 有一种大略的办法来实现这一点:HTTP 状态码。

管理状态码的基本规则是:

2xx 代表统统正常3xx 代表你想要找的公主在其余一个城堡,也便是你要找的资源在其他的地方4xx 代表客户端做错了某些事情5xx 代表做事器端失落败

我们的 API 至少要供应 4xx 和 5xx 状态码。
有时候,5xx 是自动天生的。
例如,客户端发送了一些内容到做事器端,但是这造孽的要求,而我们的校验是有缺陷的,从而导致这个问题连续在代码中实行了下去,终极导致涌现了非常,这样就会返回一个 5xx 的状态码。

如果你想要承诺利用特定的状态码,那么你会碰着“哪种状态码最适宜当前情形?”的问题。
这样的问题并不总是那么随意马虎回答,我推举你去阅读声明这些状态码的 RFC,它们给出了比其他来源更广泛的阐明,并且见告了你何时利用这些状态码更得当等。
幸运的是,网上有些资源可以帮助我们做出选择,比如Mozilla的HTTP状态码指南。

文档

精良的 API 必须要有精良的文档。
在文档方面,最大的问题在于,随着 API 的发展须要找人同步更新文档。
有个更好的方案是不分开代码自更新文档。

例如,注释与代码的脱节。
当代码发生变革的时候,注释依然保持不变,这样的话,注释就过期了。
这乃至会比根本就没有任何注释更糟糕,由于在随后的一段韶光内,它们会供应缺点的信息。
注释不会自动更新,以是开拓职员须要记得在掩护代码的时候同时掩护它们。

自更新的文档工具可以办理这个问题。
在这方面,一个盛行的工具便是 Swagger,它是基于 OpenAPI 构建的工具,可以很随意马虎地描述你的 API。

Swagger 很酷的一点在于它是可实行的,以是如果你考试测验修正 API,能立即看到它的浸染和变革。

为了给 Swagger 添加自动更新功能,我们须要利用其他的插件和工具。
在 Python 中,有针对大多数主流框架的插件。
它们能天生 API 要求该如何组织的描述,并定义数据的输入和输出。

如果你不想要利用 Swagger,而是想利用更大略的工具,那该怎么办呢?有个盛行的替代方案是Slate。

还有一些值得推举的中间方案,如widdershins和api2html的组合,它许可我们从 Swagger 的定义中天生类似 Slate 的文档。

缓存

在有些系统中,缓存可能并不是什么大问题。
这样的系统可能没有很多的数据可供缓存,所有的数据都在不断地发生变革,或者系统根本没有很大的流量。

但是,在大多数情形下,缓存对付良好的性能至关主要。
它与 RESTful API 密切干系,由于 HTTP 协议在缓存方面做了很多事情,比如 HTTP 头信息许可我们掌握缓存的行为。

你可能想要在客户端缓存东西,或者如果有注册表或值存储的话,那么你可能想要在运用程序中缓存数据。
但是,HTTP 让我们能够基本上免费就可以得到一个很好的缓存,以是如果可能的话,请不要错过这个免费的午餐。

同时,由于缓存是 HTTP 规范的一部分,以是很多涉及 HTTP 的技能都知道如何进行缓存:浏览器原生支持缓存,客户端和做事器之间的中间技能也是如此。

API 设计的蜕变

构建 API 以及当代软件最主要的部分便是适应性。
如果没有适应性,开拓就会变慢,在合理的韶光发布特性就会变得更加困难,当面对末了截止韶光的时候更是如此。

“软件架构”在不同的高下文语境中有不同的含义,不过我们现在采取这个定义:

软件架构一种行为/艺术,能够避免会阻碍未来变革的决策。

记住了这一点,在设计软件的时候,当你必须要在具有相似优点的方案中做出选择时,你该当始终选择更多考虑到未来的方案。

好的实践并不是万能的。
按照精确的办法构建缺点的东西并不是你想要的结果。
最好采纳一种发展的心态,接管变革是不可避免的,尤其是如果你的项目要持续发展的话更是如此。

要想让你的 API 更具适应性,个中很关键的一点便是保持尽可能薄的 API 层,真正的繁芜性该当往下层转移。

API 不应该限定实现

公开的 API 发布之后,它就已经完成了,是不可改变的,你就不能再去触碰它了。
如果你已经有了一个设计古怪的 API,除了接管现状之外,还能做些什么呢?

你该当不断探求简化实现的方法。
有时候,你可以通过一个特定的 HTTP 头信息来掌握 API 相应的格式,相对付构建其余一个叫做 v2 的新 API,这是一种更大略的办理方案。

API 只是其余一层的抽象。
它们不应该决定如何实现,为了避免这种问题,我们可以采取如下几种开拓模式。

API 网关

这是一种类似于门面的开拓模式。
如果你要把一个单体构造拆分为一组微做事,并且希望向外部暴露一些功能的话,那么你只须要构建一个类似门面的 API 网关。

它将为不同的微做事供应一个统一的接口(这些微做事可能有不同的 API,利用不同的缺点格式等等)。

适用于前真个后端

如果你必须要构建一个 API 来知足一堆不同的客户真个话,那么这可能会非常困难。
针对某个客户端所作出的决策可能会影响其他客户真个功能。

按照适用于前真个后端(backend for frontend)理念,如果你有不同的客户端,它们喜好不同形式的 API,比如移动运用可能会喜好利用 GraphQL,那么就单独为它们构建吧。

只有当你的 API 是一层抽象,并且这个抽象层很薄的时候,这种办法才有效。
如果它与你的数据库耦合,或者太大,具有太多的逻辑,那么就无法这样做了。

GraphQL 与 RESTful

很多人都在热炒 GraphQL。
它是一项新兴的技能,但是已经有了很多粉丝,以至于有些开拓者声称它将取代 REST。

只管 GraphQL 比 RESTful 要新的多,但是它们有很多相似之处。
GraphQL 最大的不敷之处在于它的缓存,它必须要在客户端或运用程序中实现。
现在,有内置的实现了缓存功能的客户端库(比如Apollo),但是这仍旧要比利用 HTTP 供应的险些免费的缓存功能要困难。

从技能讲,GraphQL 位于 Richardson 模型的 Level 0 层级,但是它具有良好 API 的特质。
我们可能无法同时利用多个 HTTP 的功能,但是 GraphQL 的涌现便是办理这一问题的。

GraphQL 的杀手锏便是聚合不同的 API,并将它们作为一个 GraphQL API 暴露出来。

GraphQL 在处理数据抓取不敷和数据过量抓取方面有很好的效果,而这些问题是 REST API 很难进行管理的。
这两个问题都与性能有关,如果数据抓取不敷,那解释你没有高效地利用 API,以是必须要进行大量的调用。
如果数据过量抓取的话,那么 API 调用的数据传输会比必要的数据传输更大,这是对带宽的一种摧残浪费蹂躏。

小结

借助 REST 与 GraphQL 的比较,我们能够总结出一个好的 API 最主要的品质。

好的 API 的特性

我们须要一个清晰的数据表述办法:RESTful 以资源的办法供应了表述。
我们须要有一种办法显示有哪些可用的操作:RESTful 通过组合伙源和 HTTP 动作实现这一点。
我们须要有一种办法来确认是否存在缺点/非常:HTTP 状态码可以实现这一点,可能还会包含阐述它们的相应信息。
最好能够供应 API 创造和导航的功能:在 RESTful 中,HATEOAS 卖力实现这一点。
有好的文档是非常主要的:在这方面,可实行、自更新的文档可以办理这个问题,这超出了 RESTful 规范的范围。
末了,但同样主要的是,精良的 API 该当具有缓存功能,除非你的特定情形认为它是不必要的。

REST 和 GraphQL 之间最大的差异是它们处理缓存性的办法。
当我们利用 REST 办法构建 API 的时候,我们基本上可以免费得到 HTTP 的缓存功能。
如果选择 GraphQL 的话,你须要自行卖力为客户端或运用程序添加缓存。

原文链接:

https://www.stxnext.com/blog/how-to-build-a-good-api-that-wont-embarrass-you

延伸阅读:

4种主流的API架构风格比拟-InfoQ

关注我并转发此篇文章,即可得到学习资料~若想理解更多,也可移步InfoQ官网,获取InfoQ最新资讯~

标签:

相关文章