接上篇 —— 如何使用 GraphQL-进阶教程:服务端 —— 继续翻译How to GraphQL 系列教程。
学习 GraphQL 的进阶概念,比如片段、查询参数、别名、接口和更多的 SDL 特性。
基础和进阶系列翻译已完成:
通过片段增强可复用性
片段(Fragments) 是一个方便的功能,有助于改善 GraphQL 代码的结构和可复用性。片段是特定类型字段的集合。
假设我们具有以下类型:
1 | type User { |
在这里可以将与用户的真实地址有关的所有信息表示为一个片段:
1 | fragment addressDetails on User { |
接下来在编写查询以访问用户的地址信息时,可以使用以下语法引用该片段,实际拼出了四个字段:
1 | { |
这个查询与下述代码等同:
1 | { |
对字段进行参数化
在 GraphQL 类型定义中,每个字段可以包含任意多个 参数(argument) 。与强类型编程语言传递给函数的参数类似,每个参数都必须具有 名称(name) 和 类型(type) 。在 GraphQL 中,也可以为参数指定 _默认值(default values)_。
作为示例,让我们看一下开始的 schema 的一部分:
1 | type Query { |
可以在 allUsers
字段中添加一个参数,该参数允许我们传递参数以过滤出特定年龄段的用户。还指定一个默认值,以便默认情况下将返回所有用户:
1 | type Query { |
可以使用以下语法将这个 olderThan
参数传递到查询中:
1 | { |
对查询结果使用别名
GraphQL 的主要优势之一是可以在单个请求中发送多个查询。但是由于响应数据是在请求的字段结构之后形成的,因此当发送多个询问相同字段的查询时,可能会遇到命名问题:
1 | { |
实际上这会使 GraphQL 服务器产生错误,因为它们只是参数不同的相同字段。发送这样的查询的唯一方法是使用别名,即为查询结果指定名称:
1 | { |
服务器将根据指定的别名为每个User
对象命名:
1 | { |
进阶 SDL
SDL 提供了之前章节中未讨论的几种语言功能。在下文中,将通过实例进行讨论。
对象 和 标量类型
在 GraphQL 中,有两种不同的类型。
标量(Scalar) 类型代表数据的具体单位。GraphQL 规范具有五个预定义的标量:如
String
、Int
、Float
、Boolean
和ID
对象(Object) 类型具有 _字段(field)_,它们表示该类型的属性且可组合。对象类型的示例是我们在上一节中看到的
User
或Post
类型。
在每个 GraphQL schema 中,都可以定义自己的标量和对象类型。自定义标量中经常被引用的例子是 Date
类型,其中实现需要定义如何校验、序列化和反序列化该类型。
枚举
GraphQL 允许定义 枚举(enum) 类型,这是一种语言功能,用于表达具有一组固定值的语义类型。因此,我们可以定义一个名为 Weekday
的类型来表示一周中的所有天:
1 | enum Weekday { |
注意,从技术上讲枚举是特殊的标量类型。
接口
接口(interface) 可用于以抽象方式描述类型。允许您指定实现接口时,任何具体类型都需要具有的一组字段。在许多 GraphQL schema 中,每种类型都必须具有一个 id
字段。可以通过此字段定义一个接口,然后确保所有自定义类型都必须实现该接口:
1 | interface Node { |
联合类型
联合类型(Union type) 可以用来表示一个类型应该是其他类型集合中的一个。通过示例可以最好地理解它们。如下:
1 | type Adult { |
现在,我们可以将 Person
类型定义为 Adult
和 Child
的 _联合_:
1 | union Person = Adult | Child |
这就带来了一个不同的问题:在 GraphQL 查询中,我们要求检索有关 Child
的信息,但仅具有 Person
类型的信息,如何知道是否可以实际访问此字段?
答案是 _有条件片段(conditional fragment)_:
1 | { |
前端记事本,不定期更新,欢迎关注!