所有文章 > API开发 > 比较API架构样式:SOAP与REST与GraphQL与RPC
比较API架构样式:SOAP与REST与GraphQL与RPC

比较API架构样式:SOAP与REST与GraphQL与RPC

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

为了快速且大规模地集成应用程序,我们使用协议或规范来实现API,这些协议或规范定义了通过网络传递的消息的语义和语法。这些规范共同构成了API的架构。

随着时间的推移,已经发布了不同的 API 架构风格。它们中的每一个都有自己的标准化数据交换模式。在选择上的拉扯与纠结中,人们展开了关于哪种建筑风格最佳的无休止争论。

API 时间表

API 样式随时间的变化,来源:Rob Crowley

今天,许多 API 消费者将 REST 称为“和平的 REST”,并为 GraphQL 欢呼,而十年前,REST 成为取代 SOAP 的赢家,情况正好相反。这些观点的问题在于,它们片面地选择了一项技术本身,而不是考虑它的实际属性和特性如何与手头的情况相匹配。

在本文中,我们将保持客观,按外观顺序讨论四种主要的 API 样式,比较它们的优缺点,并重点介绍它们最适合的场景。

四种主要 API 样式比较

四种主要 API 样式比较

远程过程调用 (RPC):在另一个系统上调用函数

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

最初的 XML-RPC 存在问题,因为确保 XML 有效负载的数据类型很困难。因此,后来 RPC API 开始使用更具体的 JSON-RPC 规范,该规范被认为是 SOAP 的更简单替代方案。gRPC 是 Google 在 2015 年开发的最新 RPC 版本。gRPC 提供了对负载均衡、追踪、健康检查和身份验证的可插拔支持,非常适合用于微服务之间的连接。

RPC 的工作原理

客户端调用远程过程,将参数和其他信息序列化为消息,然后将消息发送到服务器。收到消息后,服务器会反序列化其内容,执行请求的操作,并将结果发送回客户端。服务器存根和客户端存根负责参数的序列化和反序列化。

远程过程调用机制

远程过程调用机制,来源:大师99

RPC 优点

简单明了的交互。RPC 使用 GET 获取信息,使用 POST 获取其他所有内容。服务器和客户端之间交互的机制归结为调用终端节点并获得响应。

易于添加的功能。如果我们对 API 有新的要求,我们可以轻松地添加另一个执行此要求的端点:1) 编写一个新函数并将其抛到端点后面,以及 2) 现在客户端可以访问此端点并获取满足设置要求的信息。

高性能。轻量级有效载荷在网络上轻松运行,提供高性能,这对于共享服务器和在工作站网络上执行的并行计算非常重要。每天,RPC 能够优化网络层,使其在不同服务之间发送大量消息时表现得非常高效。

RPC 缺点

与底层系统紧密耦合。 API 的抽象级别有助于其可重用性。它与底层系统越紧密,它对其他系统的可重用性就越低。RPC 与底层系统的紧密耦合不允许在系统中的函数和外部 API 之间建立抽象层。这会引发安全问题,因为很容易将有关底层系统的实现细节泄露到 API 中。RPC 的紧密耦合使得可扩展性要求和松散耦合的团队难以实现。因此,客户端要么担心调用特定终端节点可能产生的任何副作用,要么尝试找出要调用的终端节点,因为它不理解服务器如何命名其函数。

可发现性低。在 RPC 中,无法内省 API 或发送请求并开始根据其请求了解要调用的函数。

功能爆炸。 创建新函数非常简单。因此,我们不是编辑现有的函数,而是创建新的函数,最终得到一大堆难以理解的重叠函数。

RPC 使用案例

RPC 模式在 80 年代左右开始使用,但这并不会自动使其过时。GoogleFacebook (Apache Thrift) 和 Twitch (Twirp) 等大公司正在内部使用 RPC 高性能变量来执行性能极高、开销低的消息传递。他们庞大的微服务系统要求内部通信必须清晰,并且要以短消息的形式进行排列组织。

命令 API。RPC 是向远程系统发送命令的正确选择。例如,Slack API 非常注重命令:加入频道、离开频道、发送消息。因此,Slack API 的设计者以类似 RPC 的风格对其进行建模,使其体积小、紧凑且易于使用。

用于内部微服务的客户特定 API。在单个提供者和使用者之间直接集成,我们不想像 REST API 那样花费大量时间通过网络传输大量元数据。gRPC 和 Twirp 具有高消息速率和消息性能,是微服务的强项。在后台使用 HTTP 2,gRPC 能够优化网络层,并使其每天在不同服务之间发送大量消息非常高效。但是,如果您的目标不是高网络性能,而是发布高度独特微服务的团队之间的稳定 API 联系,REST 将确保这一点。

简单对象访问协议 (SOAP):使数据作为服务可用

SOAP 是一种 XML 格式的高度标准化的 Web 通信协议。SOAP 在 XML-RPC 发布一年后由 Microsoft 发布,从中继承了很多东西。当 REST 紧随其后时,它们首先被并行使用,但很快 REST 赢得了人气竞赛。

SOAP 的工作原理

XML 数据格式拖后于许多形式。与海量消息结构相结合,它使 SOAP 成为最冗长的 API 样式。

SOAP 消息由

  • 一个 envelope 标签,用于开始和结束每封邮件,
  • 包含请求或响应的正文,
  • 报头(如果消息必须确定任何具体或额外要求),以及
  • 一个错误,告知在整个请求处理过程中可能发生的任何错误。
SOAP 消息示例

SOAP 消息的一个示例。来源:IBM

SOAP API 逻辑是用 Web 服务描述语言 (WSDL) 编写的。此 API 描述语言定义终端节点并描述可以执行的所有流程。这允许不同的编程语言和 IDE 快速建立通信。

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

SOAP 优点

与语言和平台无关。 用于创建基于 Web 的服务的内置功能允许 SOAP 处理通信并使响应独立于语言和平台。

绑定到各种传输协议。 SOAP 在传输协议方面非常灵活,可以适应多种情况。

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

许多安全扩展。 SOAP 与 WS-Security 协议集成,满足企业级事务质量要求。它在事务中提供隐私和完整性,同时允许在消息级别进行加密。

SOAP 消息级安全性:标头元素和加密正文中的身份验证数据

SOAP 消息级安全性:标头元素和加密正文中的身份验证数据

SOAP 缺点

如今,很多开发人员因为各种原因而对必须集成SOAP API感到头疼不已。

仅限 XML。 SOAP 消息包含大量元数据,并且仅支持请求和响应的详细 XML 结构。

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

狭义的专业知识。构建 SOAP API 服务器需要深入了解所有涉及的协议及其高度受限的规则。

繁琐的消息更新。 严格的 SOAP 架构需要额外的工作来添加或删除消息属性,这会减慢采用速度。

SOAP 使用案例

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

高度安全的数据传输。 SOAP 刚性结构、安全性和授权功能使其成为在 API 和客户端之间执行正式软件合同的最合适选项,同时遵守 API 提供者和 API 消费者之间的法律合同。这就是金融机构和其他企业用户选择 SOAP 的原因。

表述性状态传输 (REST):使数据作为资源可用

REST 是一种不言自明的 API 架构风格,由一组架构约束定义,旨在被许多 API 使用者广泛采用。

今天最常见的 API 样式最初是由 Roy Fielding 在 2000 年的博士论文中描述的。REST 提供服务器端数据,以简单的格式(通常是 JSON 和 XML)表示它。

REST 的工作原理

REST 不像 SOAP 那样严格定义。RESTful 架构应遵守 6 个架构约束:

  • 统一接口:允许以统一的方式与给定服务器交互,而不管设备或应用程序类型
  • Stateless:处理请求所需的状态,包含在请求本身中,并且服务器不存储与会话相关的任何内容
  • 缓存
  • 客户端-服务器架构:允许任何一方独立演进
  • 应用程序的分层系统
  • 服务器向客户端提供可执行代码的能力

事实上,一些服务只是在一定程度上是 RESTful 的。它们以 RPC 样式为核心,将较大的服务分解为资源,并有效地使用 HTTP 基础设施。但关键部分是使用超媒体(又名 HATEOAS),超文本作为应用程序状态引擎的缩写。基本上,这意味着REST API会为每个响应提供元数据,并附上关于如何使用该API的所有相关信息的链接。这就是使 Client 端和 Server 解耦的原因。因此,API 提供者和 API 使用者都可以独立发展,而不会阻碍他们的通信。

Richardson 成熟度模型是实现真正完整和有用的 API 的目标

Richardson 成熟度模型是实现真正完整和有用的 API 的目标,来源:Kristopher Sandoval

“HATEOAS 是 REST 的一个关键功能。这才是 REST REST 的真正原因。由于大多数人不使用 HATEOAS,他们实际上是在使用 HTTP RPC,“这是 Reddit 上表达的一些激进观点。事实上,HATEOAS 是 REST 的最成熟版本。但是,需要比目前通常使用和构建的 API 客户端更先进、更智能的 API 客户端是很难实现的。因此,即使是今天真正好的 REST API 也并不总是这样做。这就是为什么 HATEOAS 主要作为 RESTful API 设计长期发展的愿景。

当服务实现 REST 的某些功能和 RPC 的某些功能时,REST 和 RPC 之间确实可能存在灰色地带。REST 基于资源或名词,而不是基于动作或动词。

以动词为中心的 RPC 中的操作与以名词为中心的 REST 中的操作相反

以动词为中心的 RPC 中的操作与以名词为中心的 REST 中的操作相反

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

REST API

资料来源:Thomas Davis

REST 优点

分离的客户端和服务器。REST 尽可能地解耦客户端和服务器,允许比 RPC 更好的抽象。具有抽象级别的系统能够封装其细节,以更好地识别和维持其属性。这使得 REST API 足够灵活,可以随着时间的推移而发展,同时保持系统稳定。

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

缓存友好。 重用了大量 HTTP 工具,REST 是唯一允许在 HTTP 级别缓存数据的样式。相反,在任何其他 API 上实现缓存都需要配置额外的缓存模块。

支持多种格式。 支持多种格式存储和交换数据的能力是 REST 目前成为构建公共 API 的普遍选择的原因之一。

REST 缺点:

没有单一的 REST 结构。 构建 REST API 没有完全正确的方法。如何对资源进行建模以及要对哪些资源进行建模将取决于每个场景。这使得 REST 在理论上简单,但在实践中却很困难。

大有效载荷。 REST 返回大量丰富的元数据,以便客户端可以从其响应中了解有关应用程序状态的所有必要信息。对于具有大量带宽容量的大型网络管道来说,这种闲聊没什么大不了的。但情况并非总是如此。这是 Facebook 在 2012 年提出 GraphQL 风格描述的关键驱动因素。

过度获取和获取不足的问题。 如果包含的数据过多或不足,REST 响应通常会产生对另一个请求的需求。

REST 使用案例

管理 API。专注于管理系统中对象且面向众多用户的API,是最为常见的API类型。REST 帮助这些 API 具有强大的可发现性、良好的文档,并且它非常适合这个对象模型。

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

GraphQL:仅查询所需的数据

它需要对 REST API 进行多次调用,才能返回所需的员工。因此,GraphQL 的发明旨在改变游戏规则。

GraphQL 是一种描述如何发出精确数据请求的语法。对于具有许多相互引用的复杂实体的应用程序数据模型,实现 GraphQL 是值得的。

如何从 GraphQL 终端节点仅检索所需的数据

如何从 GraphQL 端点仅检索所需的数据,来源:Mohit Tikoo

如今,GraphQL 生态系统正在通过库和强大的工具(如 Apollo、GraphiQL 和 GraphQL Explorer)进行扩展。

GraphQL 的工作原理

GraphQL 从构建架构开始,架构是您可能在 GraphQL API 中进行的所有查询以及它们返回的所有类型的描述。架构构建很困难,因为它需要架构定义语言 (SDL) 的强类型。

在查询之前获得架构,客户端可以验证其查询,以确保服务器能够响应它。在到达后端应用程序时,将针对整个架构解释 GraphQL 操作,并使用前端应用程序的数据进行解析。向服务器发送大规模查询后,API 会返回包含请求数据结构的 JSON 响应。

GraphQL 中的查询执行

GraphQL 中的查询执行,来源:Jonas Helfer

除了 RESTful CRUD 操作之外,GraphQL 还具有允许来自服务器的实时通知的订阅

GraphQL 优点

类型化架构。 GraphQL 提前发布它可以做什么,从而提高其可发现性。通过将客户端指向 GraphQL API,我们可以找出可用的查询。

非常适合类似图形的数据。 数据深入到链接关系中,但不适合平面数据。

无版本控制。 版本控制的最佳实践是根本不对 API 进行版本控制。

REST 提供多个 API 版本,而 GraphQL 使用单个不断发展的版本,该版本允许持续访问新功能,并有助于提供更简洁、更易于维护的服务器代码。

详细的错误消息。 与 SOAP 类似,GraphQL 提供所发生错误的详细信息。其错误消息会涵盖所有解析程序,并明确指出出错的具体查询部分。

灵活的权限。 GraphQL 允许有选择地公开某些函数,同时保留私有信息。同时,REST 架构不会分批显示数据。要么全有,要么全无。

GraphQL 缺点

性能问题。 GraphQL 以复杂性换取其功能。在一个请求中包含过多的嵌套字段可能会导致系统过载。因此,REST 仍然是复杂查询的更好选择。

缓存复杂性。由于 GraphQL 不重用 HTTP 缓存语义,因此它需要自定义缓存工作。

大量的发展前教育。 由于没有足够的时间来弄清楚 GraphQL 的利基操作和 SDL,许多项目决定遵循众所周知的 REST 路径。

GraphQL 使用案例

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

复杂的系统和微服务。 GraphQL 能够将多个系统集成的复杂性隐藏在其 API 后面。它会将来自不同位置的数据进行聚合,形成一个全局性的架构体系。这对于随着时间的推移而扩展的传统基础设施或第三方 API 尤其相关。

哪种 API 模式最适合您的用例?

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

  • 正在使用的编程语言,
  • 您正在开发的环境,以及
  • 您必须节省的资源,包括人力和财务资源。

了解每种设计风格的所有权衡后,API 设计人员可以选择最适合项目的设计风格。

RPC 具有紧密耦合功能,适用于内部微服务,但不适用于强大的外部 API 或 API 服务。

SOAP 很麻烦,但其丰富的安全功能对于计费操作、预订系统和支付仍然是不可替代的。

REST 具有 API 的最高抽象和最佳建模。但它往往在网络上更重,也更健谈 – 如果你在移动设备上工作,这是一个缺点。

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

归根结底,尝试一下那些具有特定风格的小型用例是很有意义的,看看它们是否适合您的场景并能解决您的问题。如果是这样,请尝试扩展并查看它是否适合更多用例。

原文链接:https://www.altexsoft.com/blog/soap-vs-rest-vs-graphql-vs-rpc/

#你可能也喜欢这些API文章!