四时宝库

程序员的知识宝库

何时使用 GraphQL、gRPC 和 REST?

构建 API 是现代工程开发人员最重要的任务之一。这些 API 允许不同的系统进行通信和交换数据。虽然REST多年来一直是实现 API 的事实上的标准,但如今也出现了新的标准,例如gRPCGraphQL

本篇将讨论 gRPC、GraphQL 和 REST 的 API 架构。我们将确定每个工具的优点和缺点以及可以使用哪些工具。

什么是 API?

“应用程序编程接口”(API)是各种软件服务之间的通信通道。传输请求和响应的应用程序分别称为客户端和服务器。 API是一种外部软件组件它使程序功能可供其他程序使用。

在下面的蜜蜂图中,花充当服务器,蜂巢充当客户端,蜜蜂提供通信方式(REST API 请求)。

存在不同的 API 架构或协议,例如 REST、gRPC 和 GraphQL。

为什么 gRPC 很重要?

gRPC是 Google 开发的高性能、开源、通用远程过程调用 (RPC) 框架。它使用Protocol Buffers (protobuf)作为其接口定义语言。协议缓冲区是通过网络序列化数据的一种非常有效且快速的方法。该技术使用HTTP 2.0协议实现RPC API ;但是,服务器和 API 开发人员都无法访问 HTTP。它遵循客户端响应通信模型,由于 gRPC 能够接收来自多个客户端的多个请求并同时处理它们,因此该模型支持双向通信和流式传输。然而,gRPC在浏览器支持方面仍然相当有限。如前所述,gRPC默认使用Protocol Buffer来序列化负载数据。 Protocol Buffers是结构化数据的紧凑二进制序列化格式。使用 .proto 文件中定义的模式,它们允许跨各种语言进行高效的编码和解码。与传统 JSON 或 XML 相比,它们具有更小的尺寸和更快的处理速度等优势。

gRPC 的优点:

  1. 速度快。得益于 HTTP/2,gRPC 比 HTTP/1.1 上的 REST 更快、更高效。
  2. 支持多种语言。提供生成多种语言的客户端和服务器代码的工具。
  3. 流媒体:支持双向流媒体,允许更多交互的实时通信。
  4. 截止日期/超时:内置支持确保请求不会挂起。它自动解决重试、网络问题等。
  5. 生态系统:支持身份验证、负载均衡等。

gRPC 的缺点:

  1. 复杂:需要了解 Protocol Buffers 和 gRPC API。还必须预先定义架构。
  2. 有限的浏览器支持:由于依赖 HTTP/2,本机浏览器支持有限。
  3. 工具:虽然在不断发展,但 gRPC 工具仍不如 REST 成熟。你可以使用gRPCurl或Postman来测试此类 API。
  4. 人类不可读:由于它们是二进制的,因此很难像使用基于文本的格式(例如 XML 或 JSON)那样进行调试。


什么是协议缓冲区?

Protocol Buffers ,通常缩写为 Protobuf,是 Google 在 2008 年设计的一种方法。用于序列化结构化数据,类似于 XML 或 JSON,但由于它们是二进制的,因此更精简、更快,使其成为通信应用程序的首选与服务器或有效地存储数据。

使用 Protocol Buffer 进行数据序列化涉及几个步骤:

1、定义数据结构:首先定义文件中的数据结构.proto。这包括指定数据类型(整数、字符串、布尔值、自定义类型等)及其字段编号。例如:

2、生成源代码:使用 Protocol Buffers 编译器 ( protoc) 从文件中生成所需语言的源代码.proto。该编译器可以生成多种语言的代码,包括 Java、C++、Python 等。

3、生成可执行包:可执行包也会与 Protobuf 代码生成的源文件一起生成和部署。消息在运行时以二进制格式序列化和压缩。

4、反序列化:当接收者收到序列化数据流时,他们可以使用生成的类轻松地将其转换回结构化格式。

据数据统计,使用 Protocol buffers (ProtoBuf) 将性能提升高达 60% !


什么是 REST API?

REST (表述性状态传输)不是一个框架或库,而是一种用于构建 Web 服务和 API 的架构风格。在 REST 中,一切都是由唯一 URL 标识的资源,并且使用 HTTP 方法操作这些资源,例如 GET(用于检索资源)、POST(用于创建新资源)、PUT 或 PATCH(用于更新资源)、和 DELETE(删除资源)。

从客户端到服务器的每个请求都必须包含理解和完成请求所需的所有信息。服务器不存储请求之间的客户端上下文,从而简化了设计并提高了可扩展性。客户端和服务器的 HTTP 请求和响应主体携带资源状态的JSON 或 XML 表示形式。

REST API 的优点:

  • 简单性:使用标准 HTTP 方法和通用数据格式使 REST API 易于理解和实现。
  • 互操作性:REST API 促进了互操作性,因为无论使用何种编程语言或平台,不同的应用程序都可以无缝交互。
  • 可扩展性:REST API 的无状态特性允许轻松扩展以处理大量请求。
  • 灵活性:由于其多功能的设计原则,REST API 可以适应各种用例。

REST API 的缺点:

  • 无状态:REST 依赖于无状态事务,这意味着每个请求必须独立完成所有信息。对于需要跨多个请求维护状态的工作流程(例如电子商务网站上的购物车)来说,这可能很麻烦。
  • 有限的有效负载大小:REST 中的数据传输通常通过 JSON 或 XML 有效负载进行,如果你处理复杂的数据或许多查询,这些有效负载可能会变得相当大。这可能会导致性能问题。
  • 缺乏可发现性:REST API 本质上并不能让用户轻松理解它们提供的功能或如何与其交互,这可能会增加新用户的复杂性。
  • 复杂查询的性能:REST 可能不适合从较大资源中检索特定数据点。在这种情况下,其他选项(例如 GraphQL)可能会更有效。

REST 定义了API 应该遵循的六个架构约束,才能被视为真正的 RESTful:

  1. 客户端-服务器:这种关注点分离将客户端(使用 API 的应用程序)与服务器(提供 API 的应用程序)分开。客户端发起请求,服务器处理请求并发送响应。
  2. 无状态:从客户端到服务器的每个请求都必须包含理解该请求所需的所有信息。服务器不会在请求之间存储有关客户端的任何上下文。这简化了通信并提高了可扩展性。
  3. 统一接口:此约束定义了客户端如何与服务器交互的一组规则。这些规则包括:
  4. 基于资源:API 公开客户端可以与之交互的资源。 URL 标识资源。
  5. 标准方法:客户端使用标准 HTTP 方法(GET、POST、PUT、DELETE)对资源执行操作。
  6. 表示形式:数据以标准格式(例如 JSON 或 XML)在客户端和服务器之间交换。
  7. 可缓存:客户端可以将服务器响应标记为可缓存。这允许客户端在本地存储经常访问的数据,从而减少服务器负载并提高性能。
  8. 分层系统:该体系结构可能由客?户端和服务器之间的多个层(代理、缓存、负载均衡器)组成。这些层可以提高性能、安全性和可扩展性。
  9. 按需代码(可选):虽然不是严格强制的,但 RESTful API 可以选择将可执行代码传输到客户端。客户端可以使用此代码来扩展其功能或在本地处理数据。

当我们想要获取 ID 为 500 的用户的信息时,使用 curl 命令行工具对 https://api.example.com 地址上的 API 进行 REST API 调用的示例:

如下:curl -X GET https://api.example.com/users/500 -H "Accept: application/json"。最后一部分(Accept:application/json)是一个标头,表明客户端希望接收 JSON 格式的数据。响应是 JSON 格式的结果,200 是响应状态代码。

尽管在性能至关重要时 REST 不是最佳选择,但我们可以在这里做一些事情,例如缓存分页有效负载压缩等。

理查森成熟度指数

REST 约束告诉我们根据HATEOAS(超文本作为应用程序状态引擎)来设计 API。Richardson 成熟度指数根据这些约束的履行情况对 API 进行评级,并为正确实施 HATEOAS 想法分配最高评级(3 级)。

那么,根据 Richardson 成熟度指数,
HATEOAS API 如何在 3 级正确发挥作用呢

HATEOAS 的 全部内容是构建 API 响应:要放入哪些信息以及要链接哪些信息。你需要链接到不同资源的响应:图像、链接和其他 API。通过 REST/HATEOAS 设计,调用者已经获得了可用于获取信息的链接。调用者不需要知道如何构造 URL 来获取更多信息;它已经准备好了。只要调用它即可。

什么是 OData?


OData (开放数据协议)是一种开放标准,用于构建和使用 RESTful API 以促进数据交换。它使用 HTTP 进行数据通信,并允许对以 JSON 或 XML 格式表示的资源进行 CRUD(创建、读取、更新、删除)操作。数据被组织成“实体集”集合(数据库表)。每个实体集包含称为“实体”(表中的行)的单独数据点。

OData 的主要优点是其 RESTful API 的标准化,提供了查询和操作数据的统一方法。它直接在 URL 中提供丰富的查询功能,允许复杂的查询、过滤、排序和分页,而无需额外的 API 实现工作。

OData 应该将它用于我们需要向广泛的潜在消费者(开发人员、移动应用程序等)公开数据的场景,如果应用程序需要与来自各种来源的数据交互或直接通过 URL 执行复杂的查询而不实现此功能在服务器端,通常处于快速开发设置中。它不应该用于性能关键型应用程序或当我们不需要允许客户端控制数据查询时。

OData 定义附加到 URI 的特定关键字来操作数据检索。这些称为系统查询选项 (SQO) 。以下是一些常见示例:

$filter:筛选结果基于条件(例如,获取电子邮件包含“@??contoso.com”的客户)。

$orderby:根据特定属性对结果进行排序(例如,按价格升序对产品进行排序)。

$select:仅选择实体的特定属性(例如,仅从产品中检索名称和类别)。

$topand $skip:限制返回实体的数量(例如,获取前 10 个客户或跳过前 20 个并检索其余的)。

$expand:检索相关实体以及主实体(例如,获取客户及其关联订单)。

例如,如果我们有一个 OData 服务从产品数据库公开数据的场景,则该服务的基本 URL 可能如下所示:https://example.com/odata/Products。

现在:

1、客户端将发送 GET 请求来检索该 URL 的所有产品。


2、要按价格过滤产品,客户端可以将查询选项附加 $filter=Price gt 20到 URL,使其成为https://example.com/odata/Products?$filter=Price gt 20


3、要选择特定字段,例如每种产品的名称和价格,你将使用$select,结果为https://example.com/odata/Products?$select=Name,Price。


OData 服务的响应将是符合这些条件的产品列表,采用 JSON 或 XML 格式,仅包含所请求的属性。

什么是 GraphQL?

GraphQL是 Meta 于 2015 年发布并开源的 API 查询语言。GraphQL 基金会现在对其进行监督。 GraphQL 是一个服务器端运行时环境,使客户端能够从 API 请求所需的数据。与传统的 REST API(通常需要多个请求来获取不同的数据)不同,GraphQL 允许你在单个请求中指定所需的所有数据。 GraphQL 规范于 2015 年开源。

由于当查询发送到 API 时,GraphQL 不会过度获取或不足获取结果,因此它可以保证使用 GraphQL 构建的应用程序可扩展、快速且稳定。它还允许将多个操作组合到单个 HTTP 请求中。

GraphQL API 是根据类型和字段而不是端点来组织的。使用GraphQL 架构定义语言 (SDL),你可以将数据定义为架构。该模式充当客户端和服务器之间的契约,准确地详细说明了可以进行哪些查询、可以获取什么类型的数据以及响应是什么样子。

GraphQL 的优点:

  • 高效的数据获取:你只需请求所需的确切数据,从而消除了 REST 可能发生的过度获取或获取不足的问题。这可以显着提高性能,尤其是对于复杂的数据模型。
  • 灵活且声明性:GraphQL 使用定义可用数据以及如何访问数据的模式。该架构允许开发人员编写清晰简洁的查询来指定他们确切的数据需求。
  • 单个请求多个资源:与 REST 不同,REST 需要多个 API 调用才能从不同端点获取数据,GraphQL 允许将查询合并到单个请求中以提高效率。
  • 版本控制和向后兼容性:GraphQL 架构更改可以通过版本控制来实现,确保现有客户端不受影响,同时允许未来的增长。

GraphQL 的缺点:

  • 查询结构的复杂性:虽然灵活性是一种优势,但编写复杂的 GraphQL 查询可能具有挑战性,并且需要仔细规划可读性和可维护性。
  • 缓存:使用 GraphQL 缓存数据通常比利用内置 HTTP 缓存机制的 REST API 更复杂。
  • 安全性:GraphQL 会公开你的整个数据架构,因此适当的安全措施对于防止未经授权访问敏感数据至关重要。
  • 学习曲线:对于不熟悉 GraphQL 的开发人员来说,理解架构和查询语法涉及一个学习曲线。
  • 错误处理:如果库没有解析响应正文中状态为 200 的错误,则客户端必须使用更复杂的逻辑来处理它们。

怎么运行的:

  1. 客户端使用 GraphQL 语法定义查询,准确指定数据的结构方式以及需要哪些字段。
  2. GraphQL 服务器使用预定义的架构来确定可用数据及其与其他数据的关系。该架构定义了类型、字段以及类型之间的关系。
  3. 服务器针对架构执行查询。对于查询中的每个字段,服务器都有一个相应的解析器函数来获取该字段的数据。
  4. 服务器返回一个 JSON 对象,其中形状直接镜像查询,并填充请求的数据。

GraphQL 支持三个定义客户端与服务器交互方式的核心操作:

  1. 查询:用于从服务器检索数据。这是 GraphQL 中最常用的操作。
  2. 变更:会修改服务器上的数据。这可能涉及创建新数据、更新现有数据或删除数据。
  3. 订阅:用于在客户端和服务器之间建立实时通信。然后,每当请求的数据发生变化时,服务器就可以更新客户端。

GraphQL 请求的示例由操作和你请求或操作的数据组成,例如

此查询检索 ID 为 1 的用户的数据。它还获取该用户帖子的嵌套数据,包括其 ID 和标题。

响应是一个 JSON 对象,其中包含查询或突变请求的实际数据以及可选错误。

什么时候应该使用 GraphQL、gRPC 和 REST?

在设计应用程序时,开发人员可以从各种客户端-服务器通信协议中进行选择。使用 GraphQL、gRPC 和 REST 在当代项目中相对常见。根据你的应用程序的要求,每种协议都可以提供各种优势。

  • GraphQL是一种灵活的数据请求方法,专注于特定请求并仅提供必要的请求。其客户端驱动的性质使其有别于其他 API。客户做出所有决定而不是处理它们。 GraphQL 的优点是它与语言无关,请求是通过单个端点发出的,并且是强类型的,因为它具有架构。
  • REST是最流行的一种。当域可以被描述为一组资源时,这是非常合适的。 REST 是一种用于数据传输的无状态架构。它的优点包括完善的标准、简单的使用和良好的缓存支持。
  • gRPC是一个轻量级且快速的数据获取系统。在这里,主要区别在于它如何描述其合同谈判。它依赖于合同;架构并不是主导谈判的因素;这是服务器和客户端之间的关系。虽然处理和计算被委托给容纳资源的远程服务器,但大部分电力都在客户端使用。它的主要优点是它具有轻量级客户端、高效、使用协议缓冲区发送/接收数据,并且也是开源的。

最常见的 API 架构风格的时间线如下图所示。

因此,何时选择这些协议:

?如果你正在构建 CRUD 样式的 Web 应用程序或使用结构良好的数据,请使用
REST 。它是需要被广泛客户使用的公共 API 和服务的首选。

?如果你的 API 是私有的且与操作相关或者性能至关重要,请使用
gRPC。低延迟对于服务器到服务器的通信至关重要。它使用 HTTP/2 和 ProtoBuf 优化了效率和速度。

?如果你有一个公共 API,需要灵活地自定义请求并希望将来自不同来源的数据添加到公共 API 中,请使用
GraphQL 。在客户端-服务器通信中使用它,我们必须在一次往返中获取所有数据。

另外,还有几个更重要的方面

  • 可扩展性。额外的预防措施是必要的,因为 GraphQL 在高压力下可能会遇到足够大的图的问题。 REST API 的成本随负载线性增加,并在垂直限制内提供可预测的性能。
  • 可维护性。开发人员必须添加新字段进行修改,而不是对 API 进行版本控制,这与 GraphQL 向后不兼容并且缺乏版本控制功能。 REST 的依赖性分析更加明显;你可以看到每个字段的起源。
  • 错误处理。使用 GraphQL 时,你将始终收到 200 响应,并且任何检索问题都将记录在响应的“errors”数组中。客户端需要进行错误解析才能理解发生了什么。在向客户端提供任何信息之前,如果有任何字段丢失,REST API 允许开发人员在后端进行解析和响应。

总结:哪种 API 架构适合我?

如你所见,每种选择都有特定的用途和好处。由于没有明显的赢家,因此你应该使用什么,或者更重要的是,你想要使用什么,取决于你的目标和策略

发表评论:

控制面板
您好,欢迎到访网站!
  查看权限
网站分类
最新留言
    友情链接