概述
在本课中,我们将
- 探索客户端请求数据以及GraphQL 服务器 如何检索数据
- 了解构成 GraphQL 服务器 的组件
- 了解 GraphQL 模式 的基本语法:SDL 或 模式定义语言
GraphQL 操作的旅程
我们的应用程序需要为特定页面获取数据。
为了获取该数据,它会发送一个 GraphQL 操作 到我们的 GraphQL 服务器。应用程序将操作塑造成一个字符串,该字符串定义了它需要的 选择集 的 字段。然后,它将该操作通过 HTTP POST
或 GET
请求发送到服务器。
在服务器端
当我们的服务器接收到 HTTP 请求时,它首先会提取包含 GraphQL 操作 的字符串。它会解析并将该字符串转换为更易于操作的东西:一个树状结构的 文档,称为 AST (抽象语法树)。借助这个 AST,服务器可以根据我们模式中的类型和 字段 验证 操作。
如果存在任何错误(例如,请求的 字段 未在模式中定义,或 操作 格式错误),服务器将抛出错误并将其立即发送回应用程序。
在这种情况下,操作 看起来没问题,服务器可以“执行”它。这意味着,服务器可以继续其流程并实际获取数据。服务器会遍历 AST。
对于 操作 中的每个 字段,服务器都会调用该字段的 解析器 函数。解析器函数的任务是通过从正确的数据源(例如数据库或 REST API)中填充正确的数据来“解析”其字段。这些 数据源 不一定需要位于 GraphQL 服务器 内,它们可以是外部托管的。
通过这种方式,GraphQL 是 REST(和其他 数据源!)的强大桥梁,它将应用程序的所有数据捆绑在一起。GraphQL API 充当它们的顶层,提供一个单一接口,通过该接口可以同时查询多个数据源。
当所有 操作 的 字段 都解析完毕后,数据将被组装成一个排列整齐的 JSON 对象,其形状与 查询 完全相同。
服务器将该对象分配给 HTTP 响应主体中的 data
键,现在该返回我们的应用程序了。
返回客户端
我们的客户端接收包含它所需数据的响应,并将这些数据传递给正确的组件以渲染它们。
这就是 GraphQL 操作 的旅程!
现在我们已经从客户端到服务器再返回客户端,对整个旅程有了鸟瞰图,我们将花一些时间深入了解故事中的两个部分: GraphQL 服务器 的结构和 GraphQL 操作 的结构。
GraphQL 服务器的结构
GraphQL 服务器 是所有魔法发生的地方。让我们更深入地了解构成它的组件。
模式
GraphQL 模式 是构成我们在 GraphQL 服务器 中使用数据可以执行的所有操作的全面图片的类型和 字段 的集合。这里没有实际数据,只有活动数据将符合的形状的基本骨架。(想想蓝图!)
模式定义语言 (SDL)
GraphQL 模式 有自己的语言,称为 模式定义语言,或 SDL。
我们将简要介绍 SDL 的语法,但这并不是本课程的重点!在下一课中,我们将看到我们将使用的 GraphQL 服务器 框架 Hot Chocolate 如何让我们在 C# 中实现 GraphQL,而无需担心 SDL 语法的细节。但是,熟悉 SDL 仍然很有帮助,因为它将是 API 和客户端应用程序团队在讨论模式时使用的通用语言。
让我们看一个模式示例。
type Fruit {name: String!quantity: IntaverageWeight: FloathasEdibleSeeds: Booleannutrients: [String]}
Fruit
类型是 对象类型 的示例。我们使用 type
关键字定义 对象类型,然后是对象名称,最后是花括号。在花括号内,我们定义与该类型相关的 字段。
字段 以字段名称开头,然后是冒号 (:
),最后是该 字段 的类型。在上例中,Fruit
类型中的所有字段都是 标量 类型。
可用的 标量类型 在 GraphQL 中是 String
, Int
, Float
, Boolean
和 ID
。这些类似于任何编程语言中的 标量 类型。方括号 ([]
) 表示 List
类型。
我们可以将模式可视化为一个 图,一个节点和边的数据模型。每个 对象类型 或 标量 类型都是一个节点,每个关系(对象的 字段)是两个节点之间的边。
以下是 C# 类型如何映射到 GraphQL 类型:
C# 类型 | GraphQL 类型 |
---|---|
string | String |
int | Int |
double | Float |
bool | Boolean |
string, int, long | ID |
List<string> | [String] |
在 可空性 方面,GraphQL 使用感叹号 (!
) 来表示 非空(或 必需)字段。
相反,在 C# 中,所有类型默认都是非空类型。可空类型用 ?
表示。
字段 也可以返回 对象类型。例如,在下边的模式中,我们有一个 Vendor
类型,它包含一个 fruitCatalog
字段,它返回一个 Fruit
类型的列表。我们也可以在 Fruit
类型中添加一个新的 字段,称为 soldBy
,它返回一个 Vendor
类型。
type Fruit {name: String!quantity: IntaverageWeight: FloathasEdibleSeeds: Booleannutrients: [String]soldBy: Vendor}type Vendor {name: String!fruitCatalog: [Fruit]}
这就是我们真正开始看到 图 在 GraphQL 中的优势:当我们对类型之间的关系进行建模和遍历时。
为了利用这个 图,我们需要一个进入图的入口点。
入口点
一个 GraphQL 操作(客户端发送到 GraphQL 服务器 的内容)可以是 查询、变异 或 订阅。一个 查询 读取 数据,一个 变异 更改 数据,而一个 订阅 监听实时流式数据。
所有这三种 操作 都映射到模式中的对应类型:Query
、Mutation
和 Subscription
。让我们以 查询 为例。
type Query {mostPopularFruit: Fruit}
我们可以将 字段 视为 Query
类型中的 我们可以请求的 内容列表,类似地,Mutation
类型是 我们可以对 GraphQL API 做的事情列表。
解析器函数
对于 GraphQL 模式 中的每种类型和 字段,我们需要定义一个 解析器函数。这是一个可以为特定 字段 检索数据的函数。这些函数可以访问各种 数据源:数据库、REST API,甚至文本文件或 JSON!
解析器 遵循模式的层次结构。这意味着 name
和 quantity
在 Fruit
类型上的 字段 的解析器函数是属于 Fruit
类的方法。这使得我们的 解析器 函数与模式一样井井有条。
GraphQL 操作的结构
旅程始于客户端发送的 GraphQL 操作。我们描述了 GraphQL 操作 作为 "定义 选择集 的 字段 的字符串,[客户端] 需要”。当我们编写这个 操作 时,我们使用模式作为参考指南,了解我们能够访问哪些类型和 字段,以及它们如何相互关联。
我们知道 GraphQL 操作 可以是 查询、变异 或 订阅。让我们看看 查询 的示例可能是什么样子:
query GetMostPopularFruit {mostPopularFruit {namehasEdibleSeedssoldBy {name}}}
我们已经可以看到模式是如何被用作这个 查询 的参考。
首先,我们从 GraphQL 操作 的类型开始,在本例中是 query
,然后是我们选择的 操作名称,GetMostPopularFruit
,然后是花括号。在花括号内,我们可以开始添加 字段 来自 Fruit
类型:name
、hasEdibleSeeds
、soldBy
。由于 soldBy
是一个返回 Vendor
类型的 字段,我们也添加了该类型中的 字段,例如 name
。
从视觉上,我们也可以将此视为遍历 图。
在本课程中,我们将使用名为 Apollo Sandbox Explorer 的工具,它将帮助我们轻松构建查询,而无需了解应该遵循的语法的具体细节。
练习
将项目从该框拖到上面的空白处
变化
连接
问题
查询
订阅
屏幕截图
关键要点
- 有三种类型的 GraphQL 操作: 查询、突变 和 订阅。一个 查询 读取 数据,一个 突变 改变 数据,一个 订阅 监听实时流数据。
- 的 GraphQL 模式 是一个类型和 字段 的集合,它们构成了对我们在 GraphQL 服务器 中可以使用的数据的所有操作的全面概述。它是用 模式定义语言 (SDL) 编写的。
- 一个 解析器 函数检索我们模式中特定 字段 的数据。这些函数可以访问各种 数据源: 数据库、REST API,甚至文本文件或 JSON。这些数据源不需要位于 GraphQL 服务器 中。
接下来
本课程是关于构建一个 GraphQL 服务器,所以让我们开始吧!准备好一杯热饮,准备好,是时候来认识 Hot Chocolate 了。
分享你关于本课的问题和评论
本课程目前处于
你需要一个 GitHub 帐户才能在下面发布。没有帐户? 改为在我们的 Odyssey 论坛上发布。