65.9K
CodeProject 正在变化。 阅读更多。
Home

使用 HotChocolate 构建 GraphQL API

starIcon
emptyStarIcon
starIcon
emptyStarIconemptyStarIconemptyStarIcon

1.44/5 (2投票s)

2024 年 2 月 6 日

CPOL

6分钟阅读

viewsIcon

2052

downloadIcon

42

如何使用 HotChocolate 构建 GraphQL API?

引言

创建 API 最初看起来很简单:需要建立带有合适动词的端点,以便客户端可以检索或提交数据。但是,当需要新的属性或客户端不需要所有返回的数据时,就会出现问题。这通常会导致为高度特定的请求创建自定义端点,从而需要进行大量的代码维护。

为了规避这种维护噩梦的挑战,Facebook 在 2010 年代初开创的一项新技术 GraphQL 被引入。GraphQL 提供了对我们 API 中数据的全面而易于理解的表示,使客户端能够请求他们所需的确切信息,不多也不少。

在整个系列中,我们将深入探讨 GraphQL 的精确本质,并阐明其被广泛采用的原因。我们将通过实际示例来演示该概念,这些示例将专门使用相应的库 HotChocolate 以 C# 编写。

以下书籍对本系列的总结有所助益。

本文最初发布于: 使用 HotChocolate 构建 GraphQL API

什么是 API?

API 是一组规则和工具,允许不同的软件应用程序相互通信。API 定义了应用程序可以用来请求和交换信息的​​方法和数据格式。例如,作为开发人员,如果我们希望让客户能够获取有关账户或客户的信息,我们可以提供一个使用 GET 方法执行这些操作的端点。

这种设计在行业中得到广泛认可,此外,它还为所有应用程序建立了统一的标准化的接口。

这个过程本身并没有什么问题;它被广泛使用并普遍接受。它易于理解、实现,并能有效满足需求。此外,它可以在各种编程语言(如 C#、Java 等)中使用,并被不同的客户端(移动设备、JavaScript 等)使用。在理想情况下,一切似乎都很完美。

当其中一个客户端有特殊要求时会发生什么?

在上文的图中,描绘了一个能够获取客户数据的移动应用程序。但是,让我们考虑一种情况,该应用程序的用户开始对页面加载延迟表示担忧。经过调查,这似乎是因为 GET/customers 端点返回了过多的不必要数据。

现在我们有两个用于获取客户数据的端点。

但现在考虑 Java 客户端有相反的要求:返回的数据不足,它希望在有效负载中获取更多信息。

现在我们有三个用于获取客户数据的端点。

此时,所有应用程序拥有统一界面的优势就会减弱,因为我们正走向每个客户端几乎都需要专用后端的局面。此外,如果需要对其他一些请求进行类似的调整,维护复杂性就会变得难以承受。此外,获取所有信息可能需要执行多个请求。为了应对这一挑战,GraphQL 在 2010 年代初被引入。

什么是 GraphQL?

GraphQL 是一种用于 API 的查询语言,也是一种用于使用现有数据执行这些查询的运行时。它由 Facebook 于 2012 年开发,并于 2015 年开源。GraphQL 通过允许客户端只请求他们需要的数据,提供了比传统 REST API 更高效、更灵活的替代方案。

  • 客户端可以指定他们所需响应的结构,服务器将仅用这些数据进行响应。这有助于减少过度获取(接收比需要更多的数据)或获取不足(未能获得足够的数据)。

  • 可以在单个请求中检索多个资源,无需与服务器进行多次往返。

GraphQL 不与任何特定的数据库或存储系统绑定,并且可以与各种编程语言一起使用。它因其简化数据获取并提供更量身定制的 API 开发方法的能力而广受欢迎。

但是,这种魔力是如何实现的呢?

GraphQL 仅仅是一个规范,其目标之一是使客户端能够接收他们所请求的内容。为了实现这一点,客户端和服务器必须就交换的数据进行协商,而 GraphQL 的目标就是促进和完成这种协商。

这种协商无法通过传统 API 实现;它需要在服务器端安装一个运行时。这个有形运行时是 GraphQL 规范的实现。

信息

HotChocolate 是 GraphQL 规范的 C# 实现的一个例子。

服务器和客户端之间如何建立通信?

通过在类型上定义类型和字段,然后为每个类型上的每个字段提供函数来创建 GraphQL 服务。
https://graphql.net.cn/learn/

因此,可交换的数据是在服务器端定义的(具体的实现将再次取决于所选的运行时)。例如,对于我们的 customer,我们可以如下进行设置。

{
    type customer {
        id : string     
        name : string
        age : float
    }
}

在这里,我们直接声明存在一个类型为“customer”的实体,具有三个属性。

重要提示 1

上面用来表示实体的符号是个人选择,并非 GraphQL 规范所强制要求。

重要提示 2

本质上,GraphQL 只涉及为数据定义一个类型系统,并实现一个服务器运行时来根据该类型系统处理查询。

在实践中,定义的类型系统可以更加复杂,包含嵌套对象,因此得名 GraphQL。

{
    type customer {
        id : string  
        name : string
        age : integer
        commands : [command]
    }
	
    type command {
        reference : string
        amount : float
    }
}

GraphQL 允许我们定义服务器理解的类型系统,使其能够只返回请求的数据。在这方面,GraphQL 可以被概念化为一个查询语义引擎,为查询注入智能,而不仅仅是通过 GETPOST 请求检索完整的 JSON 数据。

一旦定义了我们的数据,下一步就是在客户端进行查询。

客户端请求数据

这就是我们利用服务器端所有基础设施的好处所在:在查询 GraphQL 服务器上的数据时,我们可以精确地只选择所需的信息,不多也不少。此外,由于智能现在嵌入在查询及其有效负载中,因此不再需要像传统 REST API 那样使用多个端点,只有一个端点就足够了(这个单一端点通常被指定为 /graphql)。唯一的要求是 GraphQL 客户端,特别是能够向 GraphQL 服务器发出请求的库。所有编程语言都有自己的 GraphQL 客户端可用,在本系列中,我们将使用 JavaScript。

信息

GraphQL 请求可以使用 GETPOST 方法执行,但在本系列中,我们将仅使用 POST 请求。

重要

本文仅概述了 GraphQL 的理念。我们省略了与该规范相关的许多复杂性,包括订阅或突变等高级功能。这些概念将在更高级的教程中介绍。

但现在理论够多了。我们将使用 HotChocolate 库在 C# 中深入探讨 GraphQL 服务器的实际实现。但为了避免使本文过于冗长,有兴趣进行此实现的读者可以在此处找到后续内容。

历史

  • 2024 年 2 月 6 日:初稿
© . All rights reserved.