毕业论文
您现在的位置: 版本控制 >> 版本控制前景 >> 正文 >> 正文

4种主流API架构风格对比

来源:版本控制 时间:2022/11/2

本文主要讨论了四种API架构的风格,阐述了各自的优缺点,并介绍了每种API架构适合的情况。

两个单独的应用程序需要中介程序才能相互通信。因此,开发人员经常需要搭建桥梁——也就是应用程序编程接口(API),来允许一个系统访问另一个系统的信息或功能。

为了快速、大规模地集成不同的应用程序,API使用协议或规范来定义那些通过网络传输的消息的语义和信息。这些规范构成了API的体系结构。

在过去,人们已经发布了多种不同的API架构风格。每个架构风格都有它独有的标准化数据交换的模式。这一系列的API架构风格的选项,引发了大量的关于哪种架构风格才是最好的争论。

不同时间的API架构风格,图源:RobCrowley

今天,许多API的使用者将REST称作“消亡的REST”(RESTinpeace),并且为GraphQL感到欢欣鼓舞。而十年前,又完全是另一幅光景:REST是替代SOAP的赢家。这些观点的问题在于,它们的出发点只是为某种技术背书,而不是去考虑它实际的属性和特性如何与当前的需求相匹配。

四种API架构风格

01

RPC:调用另一个系统的函数

远程过程调用是一种允许在不同上下文中远程执行函数的规范。RPC扩展了本地过程调用的概念,并将其放在HTTPAPI的上下文中。

最初的XML-RPC是存在问题的,因为很难确保XML有效负载的数据类型。因此,后来RPCAPI开始使用一个更具体的JSON-RPC规范,该规范被认为是SOAP的更简单的替代方案。gRPC是Google在年开发的最新RPC版本。gRPC可插拔支持负载均衡、追踪、运行状况检查和身份验证,它非常适合连接不同的微服务。

RPC的工作机制

客户端调用一个远程的过程,将参数和附加信息序列化为消息,然后将消息发送到服务端。服务端在接受到消息后,将信息的内容反序列化,执行所请求的操作,然后将结果发送回客户端。客户端和服务端各自负责参数的序列化和反序列化。

远程过程调用的机制,图源:Guru99

RPC的优势

简单直接的交互。RPC使用GET来获取信息,使用POST来处理其他所有操作。服务端和客户端之间交互的机制归结为调用端点并获得响应。

易于添加新函数。如果API有了新的需求,我们可以轻松地添加另一个执行这个需求的端点:1)编写一个新函数,并将其放在一个新端点之后;2)现在,客户可以访问这个端点,并获取符合其需求的信息。

高性能。轻量级的有效负载不会对网络产生压力,以此提供高性能,这对于共享服务器和在工作站网络上执行并行计算非常重要。RPC还能够优化网络层,使得不同服务之间每天发送海量消息变得非常高效。

RPC的不足

和底层系统紧密耦合。API的抽象级别有助于其可重用性。API与基础系统的耦合越紧密,对其他系统的可重用性就越差。RPC与基础系统的紧密耦合不允许其在系统函数和外部API之间建立抽象层。这很容易引起安全问题,因为关于基础系统的细节实现很容易会泄漏到API中。

RPC的紧密耦合使得可伸缩性要求和松散耦合的团队难以实现。因此,客户端要么会担心调用特定端点的带来的任何可能的副作用,要么需要尝试弄清楚要调用的端点,因为客户端不了解服务器如何命名其函数。

可发现性低。在RPC中,无法对API进行检验总结,或者发送请求来开始理解根据需求应该调用哪个函数。

函数爆炸性增长。创建新函数非常容易。因此,相较于重新编辑现有的函数,我们会倾向于创建新的功能,最终产生大量难以理解的、功能重叠的函数。

RPC的用例

RPC模式在八十年代开始使用,但这并不意味着它已经过时了。诸如Google、Facebook(ApacheThrift)和Twitch(Twirp)这样的大公司如今正在内部使用高性能的RPC版本,来执行极高性能、低开销的消息传递。它们庞大的微服务系统要求内部通信在使用短消息的情况下也保持清晰。

命令API。RPC是用于将命令发送到远程系统的正确选择。例如,SlackAPI是非常以命令为中心的:加入频道、离开频道、发送消息。因此,SlackAPI的设计者以类似于RPC的样式对其进行了建模,使其小巧、紧凑并且易于使用。

用于内部微服务的客户特定的API。由于是在单个提供者和单个使用者之间建立直接的集成,我们不想像RESTAPI那样,花太多时间通过网络传输大量的元数据。凭借高消息速率和消息性能,gRPC和Twirp成为了用于微服务的可靠用例。通过在底层使用HTTP2,gRPC能优化网络层,使其非常高效地在不同服务之间每天传送大量信息。然而,如果你并不是要着眼于提高网络性能,而是要在发布高度独立的微服务团队之间建立一个稳定的API联系。REST就能做到。

02

SOAP:使数据作为服务可用

SOAP是一个XML格式的、高度标准化的网络通讯协议。在XML-RPC发布的一年后,SOAP由微软发布、并继承了许多XML-RPC的特性。在REST紧随其后发布,一开始它们是被同时使用,但很快REST赢得了这次比赛,成为了更流行的协议。

SOAP的工作机制

XML数据格式拖累了很多数据规范。伴随着大量的消息结构,XML数据格式使得SOAP成为了最冗长的API架构风格。

SOAP的消息由这些部件组成:

一个信封标签:用于开始和结束每条消息包含请求或响应的正文一个标头:用于表示消息是否由某些规范或额外要求的来确认故障通知:包含了可能在请求处理过程能够发生的任何错误

一个SOAP消息的例子,图源:IBM

SOAPAPI的逻辑由Web服务描述语言(WSDL)编写。该API描述语言定义了端点并描述了可以执行的所有过程。这使得不同的编程语言和IDE能够快速建立通信。

SOAP支持有状态和无状态消息传递。在有状态的情况下,服务器存储接收到的信息可能非常繁琐复杂。但这对于涉及多方和复杂交易的操作是合理的。

SOAP的优势

独立于语言和平台。内置创建Web服务的功能使得SOAP能够处理消息通信的同时发送独立于语言和平台响应。

绑定到各种协议。SOAP在适用于多种场景的传输协议方面是十分灵活的。

内置错误处理。SOAPAPI规范允许返回带有错误码及其说明的的XML重试消息。

一系列的安全拓展。SOAP与ES-Security集成,因此SOAP可满足企业级事务要求。它在事务内部提供了隐私和完整性,同时允许在消息级别进行加密。

SOAP消息级别的安全性:在标头元素的认证数据以及加密的正文

SOAP的不足

如今,由于如下几种原因,许多开发人员在听到必须集成SOAPAPI的想法后都会感到不安。

仅使用XML。SOAP消息包含大量的元数据,并且在请求和响应时仅支持繁冗的XML格式。

重量级。由于XML文件的大小,SOAP服务需要很大的带宽。

非常专业化的知识。构建SOAPAPI服务器需要对所有涉及到的协议以及它们及其严格的限制都有很深的了解。

乏味的消息更新。由于需要额外的工作来添加或者删除某个消息属性,这种死板的SOAP模式减慢了其被采用的速度。

SOAP的用例

目前,SOAP体系结构最常用于企业内部或与其信任的合作伙伴的内部集成。

高度安全的数据传输。SOAP严格的消息结构,安全性和授权功能使其成为在API和客户端之间执行正式软件协议的最合适的选择,同时又符合API提供者与API使用者之间的法律合同。这就是为什么金融组织和其他企业用户选择使用SOAP的原因。

03

REST:使数据作为资源可用

REST如今是一种无需解释的API架构风格,它由一系列的架构约束所定义,旨在被广泛API使用者采用。

当前最常见的API架构风格最初由RoyFielding在其博士论文中提出的。REST使得服务端的数据可用,并以简单的格式(通常是JSON和XML)来表示它。

REST的工作机制

REST的定义并不像SOAP那样严格。RESTful体系结构应该遵守如下六个体系结构约束:

统一接口:无论设备或应用程序类型如何,都可以采用统一的方式与给定的服务端进行交互。无状态:请求本身包含处理该请求所需要的状态,并且服务端不存储与会话相关的任何内容。缓存客户端-服务器体系结构:允许双方独立发展应用程序的层级系统服务端向客户端提供可执行代码的能力

实际上,某些服务仅在某种程度上是RESTful的。而它们的内核采用了RPC样式,将较大的服务分解为资源,并有效地使用HTTP基础结构。但REST的关键部分是超媒体(又称HATEOAS),是超文本作为应用程序状态引擎(HypertextAsTheEnginerOfApplicationState)的缩写。基本来说,这意味着RESTAPI在每个响应中都提供元数据,该元数据链接了有关如何使用该API的所有相关信息。这样便可以使客户端和服务端解耦。因此,API提供者和API使用者都可以独立发展,而这并不会阻碍他们的交流。

理查森成熟度模型作为实现真正完整且有用的API架构的目标。图源:KristopherSandoval

“HATEOAS才是REST的关键功能,因为它真正使得REST成为REST。但由于大多数人不使用HATEOAS,因此他们实际上是在使用HTTPRPC。”这是Reddit上表达的一些激进观点。确实,HATEOAS是REST的最成熟版本。

但是,这非常难以实现,因为这要求API客户端要比它们如今构建和使用的方式变得更先进和智能得多。因此,即便是如今非常好的RESTAPI也不一定总是能做到这一点。这就是为什么HATEOAS主要是作为RESTfulAPI设计的长期开发的愿景而存在。

当服务端实现REST的某些功能和RPC的某些功能时,在REST和RPC之间确实可能存在这样一个灰色区域。但REST是基于资源或名词的,而不是基于动作或动词。

以动词为中心的RPC模型和以名词为中心的REST模型中的操作对比

在REST中,使用例如GET、POST、PUT、DELETE、OPTIONS可能还有PATCH等HTTP方法来完成操作。

图源:ThomasDavid

REST的优势

客户端和服务端的解耦:由于REST尽可能地解耦了客户端和服务端,REST相较于RPC可以提供更好的抽象性。具有抽象级别的系统能够封装其实现细节,以更好的标示和维持它的属性。这使得RESTAPI足够灵活,可以随着时间的推移而发展,同时保持稳定的系统。

可发现性:客户端和服务端之间的通信描述了所有内容,因此不需要外部文档即可了解如何与RESTAPI进行交互。

缓存友好:REST重用了许多HTTP工具,也是唯一一种可以在HTTP层面上缓存数据的API架构风格。与其相对的是,在任何其他API上实现缓存都需要配置其他缓存模块。

多种格式支持:REST拥有支持多种格式用于存储和交换数据的能力,这是它如今成为搭建公共API的主要选择的原因之一。

REST的不足

没有标准的REST结构:在构建RESTAPI方面,没有具体的正确方法。如何对资源进行建模以及哪些资源需要建模取决于不同的情况。这使得REST在理论上很简单,但在实践中却很困难。

庞大的负载:REST会返回大量丰富的元数据,以便客户端可以仅从响应中了解有关应用程序状态的所有必要信息。对于具有大量带宽容量的大型网络系统来说,这种“啰嗦”的通信并不算很大的负载。但带宽容量并非总是足够的。这也是Facebook在年提出GraphQL架构风格的关键驱动因素。

响应过度和响应不足问题。REST的响应包含的数据会过多或不足,通常会导致客户端需要发送另一个请求。

REST的用例

管理API。在系统中,专注于管理对象并面向许多使用者的API是最常见的API类型。REST帮助此类API具有强大的可发现性,良好的文档编制,因此REST非常适合此对象模型。

简单的资源驱动型应用程序。在用于连接不需要查询灵活性的资源驱动型应用时,REST是一种非常有效的方法。

04

GraphQL:仅请求所需要的数据

RESTAPI需要被多次调用才能返回所需要的资源。所以,GraphQL被发明了,并改变了这一切游戏的规则。

GraphQL是一种语法,它描述了如何进行精确的数据请求。有些应用程序的数据模型具有许多相互引用的复杂实体,在这种情况下,实现GraphQL是值得的。

如何从GraphQL端点仅获取所需要的数据,图源:MohitTikoo

如今,GraphQL的生态系统正在蓬勃发展,出现了例如Apollo、GraphiQL和GraphQLExplorer等强大的库和工具。

GraphQL的工作机制

GraphQL从构建模式(Schema)开始。模式是对于用户可以在GraphQLAPI中进行的所有查询及其返回的所有类型的描述。模式构建非常困难,因为它需要使用模式定义语言(SDL)进行强类型化。

因为在客户端进行查询之前已经定义好了模式,所以客户端可以验证其查询语句,以确保服务端能够对查询语句进行响应。在查询语句到达后端应用程序时,GraphQL操作将根据整个模式进行解释,并向前端应用程序返回解析到的数据。API向服务端发送一个庞大的查询,该API返回一个仅包含我们所需数据的JSON响应。

GraphQL的查询语句执行,图源:JonasHelfer

除了包含RESTful的CRUD操作,GraphQL还有订阅(subscriptions)机制,允许接收来自服务端的实时通知。

GraphQL的优势

具有类型的模式:GraphQL提前公开了它能做什么,从而提高了其可发现性。通过将客户端指向GraphQLAPI,我们可以发现什么查询语句是可用的。

没有版本控制:版本控制的最佳实践是不要对API进行版本控制。

尽管REST提供了不同的API版本,GraphQL使用的是不断更新的单一版本,这使用户可以持续访问新功能,并有助于提供更整洁、更可维护的服务器代码。

详细的错误消息:GraphQL以类似于SOAP的方式提供所发生错误的详细信息。它的错误消息包括所有解析器,并指向确切的发生故障时的查询部分。

灵活的权限:GraphQL允许选择性地公开某些功能,同时保留私人信息。而相对应的是,REST体系架构不能仅显示部分数据,要么是全部数据,要么是没有数据。

GraphQL的不足

性能问题。GraphQL权衡了复杂性,来实现其强大功能。一个请求中的嵌套字段太多会导致系统过载。因此,对于复杂的查询,REST仍然是更好的选择。

缓存复杂度。由于GraphQL不再使用HTTP缓存语义,因此使用者需要额外自定义缓存。

大量的预开发教育。由于没有足够的时间来了解GraphQL的某个操作和SDL,因此许多项目决定采用众所周知的REST方法。

GraphQL的用例

移动API。在这种情况下,网络性能和单个消息有效负载优化很重要。因此,GraphQL为移动设备提供了更有效的数据加载方式。

复杂的系统和微服务。GraphQL能够隐藏其API背后的多个系统集成的复杂性。GraphQL从多个地方聚合数据,并将它们合并为一个全局的模式。对于随时间推移而逐渐扩展的遗留基础架构或第三方API来说,这尤其重要。

05

哪种API模式最适用你的用例?

每个API项目都有不同的限制和需求。通常,API架构的选择取决于:

所使用的编程语言,你的开发环境,以及你的资源预算,包括人力资源和财务资源。

在了解了每种设计风格的利与弊之后,API设计人员可以选择最适合项目的那一种。

具有强耦合性的RPC很适用于内部微服务,但它对外部API或者API服务而言不是一个好的选择。

SOAP的使用有些麻烦,但它强大的安全拓展使它在计费操作、预订系统和支付方面是无可替代的。

REST是针对API的最高级别的抽象和最佳模型。但它往往会有些“啰嗦”而增加系统的负担——如果你使用的是移动设备,这是个问题。

GraphQL在数据获取方面向前迈出了一大步,但并不是每个人都有足够的时间和精力来掌握它。

归根结底,去针对一些小型的用例来尝试某种特定API架构,并去了解它是否适合你的用例以及是否解决了你的问题,这样做是比较合适的。如果它适用于你的用例,就可以尝试扩展并查看它是否适用于更多的用例。

原文链接:

转载请注明:http://www.0431gb208.com/sjsbszl/2259.html