API(Application Programming Interface) 是软件开发的基本组成部分,允许不同的系统和应用程序交互和共享数据。用于构建和使用 API 的各种工具、标准和协议称为 API 技术。它们可以包括协议规范或架构、安全协议和数据格式,例如 JSON 或 XML。
Representational State Transfer (REST) 通常被认为是 API 架构的黄金标准协议。但是,出现了一种流行的新替代方案,称为 GraphQL,它包含几个 REST 所没有的独特功能。其中包括允许客户端仅请求他们需要的特定数据并在单个请求中查询多个资源。
在 REST 和 GraphQL 之间进行选择通常取决于项目的具体要求。 REST 非常适合简单、文档齐全的 API,而 GraphQL 更适合复杂、不断发展的 API。
在本文中,我们将深入研究 REST 和 GraphQL 的基本原理并比较它们的优缺点,以帮助我们确定何时使用它们。
让我们首先探讨在 REST(或 RESTful)架构中工作时的一些重要主题。
REST API 用于实现不同软件系统和应用程序之间的通信和数据交换。 REST API 为应用程序使用 HTTP 协议通过 Internet 进行通信提供了一种标准方式。 REST 提供了一组用于开发 Web 服务的指南,称为 REST 体系结构原则。这些包括:
在 REST 架构中,每个资源都由一个唯一的 URI 标识,并且可以使用标准的 HTTP 方法进行访问。
REST 于 2000 年由 Roy Fielding 作为其博士论文的一部分首次引入,并因其简单灵活的特性而迅速流行起来。它还利用了现有的 Web 基础架构,使其易于使用标准 HTTP 客户端库进行交互。
Roy Fielding是HTTP协议(1.0版和1.1版)的主要设计者、Apache服务器软件的作者之一、Apache基金会的第一任主席
REST API 用于构建各种类型的 Web 应用程序,例如电子商务平台、社交媒体网络、内容管理系统和移动应用程序。它们使开发人员能够创建独立于平台的 API,从而可以集成使用不同编程语言和技术构建的应用程序。
REST API 的一些常见用例包括从远程服务器检索数据、更新服务器上的数据、创建新数据以及从服务器删除数据。 REST API 通常用于为现代 Web 应用程序的后端提供支持,使它们能够与客户端框架和库(如 React、Angular 或 Vue)进行通信。
总体而言,REST API 在现代软件开发中发挥着至关重要的作用,使应用程序能够无缝通信和共享数据,为构建可伸缩和可扩展的 Web 应用程序提供基础。它们确实带来了挑战,我们将在下一节中介绍这些挑战。
使用 REST API 时的一些常见挑战包括可能过度获取或获取不足的数据,这可能会导致服务器和客户端的额外负载。在接下来的部分中,我们将更详细地探讨这两个问题。
当客户端接收到超出他们请求的特定子集的不必要数据时,就会发生过度获取,这可能会导致服务器端和客户端出现问题,因为服务器返回未使用的数据,而客户端接收到不需要的数据。
让我们通过一个例子来观察过度获取是如何发生的。
假设我们正在为客户端应用程序构建用户配置文件页面,并且我们只有 /users/:id 端点可用于获取用户信息。我们只需要用户的姓名和地址。要获取此信息,我们很可能会像这样发出 HTTP GET 请求:
GET https://example.com/users/1
然后服务器将返回响应正文中的信息,通常采用 JSON 或 XML 格式:
{
"id": 1,
"name": "John Smith",
"age": 33,
"email": "john.smith@example.com",
"phone": "555-555-5555",
"address": {
"street": "123 Main St",
"city": "Anytown",
"state": "CA",
"zip": "12345"
},
"occupation": "Self Employed",
"status": "active",
"created_at": "2023-01-01T00:00:00.000Z"
}
虽然该响应为我们提供了任务所需的姓名和地址,但它还包括其他数据,例如年龄、电子邮件、电话、职业、状态和 创建时间。
对于较大的应用程序,过度获取成为一个更容易暴露的问题,它会在更大的范围内多次发生。将资源浪费在处理大量不必要的数据上会对客户端应用程序的性能产生重大影响。
相比之下,提取不足涉及向服务器发出大量额外请求以检索必要的数据。在这种情况下,API 端点无法提供足够的数据来满足客户端的请求,导致客户端需要发出额外的请求。这可能会导致网络使用量增加、延迟增加和性能下降。例如,如果 API 端点旨在返回单个用户的姓名和电子邮件,但客户端还需要用户的地址,则将需要另一个 API 请求来检索该信息。
回到前面的例子,假设除了需要用户的姓名和地址之外,我们还需要他们的朋友信息列表。我们仍然可以使用 /user/:id 端点,但现在已改进为仅返回以下内容:
{
"id": 1,
"name": "John Smith",
"address": {
"street": "123 Main St",
"city": "Anytown",
"state": "CA",
"zip": "12345"
},
"friends": [2,3,4,5,6]
}
friends 字段仅包含用户好友的用户 ID 列表。返回字段中的 ID 列表而不是对象列表可以减少通过网络发送的数据量。但是,因为我们需要每个朋友的姓名和地址,所以我们现在需要进行以下单独请求以获取此信息:
GET https://example.com/user/2
GET https://example.com/user/3
GET https://example.com/user/4
GET https://example.com/user/5
GET https://example.com/user/6
获取过度和获取不足都可能导致性能问题和不必要的网络使用,因此仔细设计 API 端点以提供必要的数据而不返回过多或不足的数据非常重要。解决这些问题的一种方法是使用 GraphQL,它使客户端能够仅请求他们需要的数据,避免过度获取或获取不足。
GraphQL 是一种用于构建灵活、高效且强大的 API 的查询语言。它最初由 Facebook 于 2012 年开发,随后于 2015 年开源,此后在开发者社区中获得了极大的关注。
在 GraphQL 中,客户端通过使用 GraphQL 查询语言发出请求来定义必要数据的结构。这些请求由一系列字段组成,这些字段定义了所请求数据的形状,每个字段都包含自己的一组子字段。然后,服务器使用与查询形状匹配的 JSON 对象响应请求。
通过允许客户端通过单个端点而不是一组固定的端点来表达他们的数据需求,GraphQL 避免了过度获取和获取不足的可能性。
在接下来的部分中,我们将讨论 GraphQL 背后的其他一些核心概念。
在 GraphQL 中,我们使用查询从服务器获取数据。它们允许我们指定所需的数据,通常用于只读操作。
以下是我们如何使用 GraphQL 查询请求特定用户对象的示例:
query {
user(id: 1) {
id
name
address
}
}
此查询请求用户对象的 id、name 和 address 字段,并指定请求用户的 id 为 1。
回想一下前面请求某个用户的朋友列表以及他们的姓名和地址的示例。使用 GraphQL,我们可以在每个被查询的好友对象下请求我们要查找的特定信息:
query {
user(id: 1) {
id
name
address
friends {
id
name
address
}
}
}
通过查询(Query),我们现在可以轻松地在单个请求中检索所需的所有信息,而不是像使用 REST API 那样将多个请求分散到多个端点。
我们可以使用变更来更改服务器数据,通常用于创建、更新和删除操作。下面是一个示例,说明如何使用 GraphQL 变更来创建新的用户对象:
mutation {
createUser(input: { name: "Alice", address: "123 Main St" }) {
id
name
address
}
}
mutation 使用提供的名称和地址创建一个新的用户对象,并请求创建的用户对象的 id、name和address字段。
在服务器端,GraphQL 架构通常由两个主要元素组成:
模式定义了系统中可用数据的类型,它们之间的关系通常用 GraphQL 模式定义语言 (SDL) 编写。它还定义了服务器可以提供的数据结构,以及我们可以为访问该数据而进行的查询和更改的结构。
解析器是处理 GraphQL 查询执行的服务器函数。他们负责获取相应字段的数据。
在客户端,我们可以使用 GraphQL 客户端库与 GraphQL 服务器进行交互。 GraphQL 客户端库简化了发出 GraphQL 请求和解析响应的过程。
现在我们已经知道 REST 和 GraphQL 之间的区别,让我们探讨一些我们可以选择其中之一的场景。
REST 易于理解,这使其成为构建仅需要基本创建、读取、更新和删除 (CRUD) 操作的简单 API 和应用程序时的绝佳选择。如果 API 不需要复杂的查询,GraphQL 的特殊性就没有必要了。
在关注性能的情况下,REST 通常是更好的解决方案。 REST API 往往具有更简单和更可预测的数据结构,这允许服务器更快地返回数据。在这种情况下,发出多个请求是有益的,因为较小的数据块更容易处理和处理。同时,使用 GraphQL 发送复杂查询会减慢服务器响应时间。
GraphQL 是一个高度灵活的选项,更适合构建需要复杂数据获取和操作的 API。它巧妙地避免了过度获取和获取不足的数据,从而降低了带宽使用率并加快了响应时间。
此外,GraphQL 更擅长构建需要来自多个来源的数据的 API。 REST API 需要发出多个 HTTP 请求,而 GraphQL 允许客户端发送单个查询以从多个源检索数据作为单个 JSON 对象。
使用 GraphQL 的另一个好处是,当服务器端的数据模型或服务发生变化时,调用端无需更改请求或修改端点。我们可以继续接收相同格式的相同数据字段,从而更好地协调我们的数据和服务器数据,并改善开发人员体验。
归根结底,这两种技术的流行都是有原因的。
GraphQL 是一种高度灵活的查询语言,可以比传统的 REST API 更轻松、更详细地表达复杂的数据需求。但是,如果我们构建的 API 只需要基本的 CRUD 操作和简单的查询,REST API 可能是更直接、更高效的解决方案。
最佳选择取决于项目的具体需求和目标。
【完】