- 学习GraphQL类型系统
- 类型系统如何描述可以查询的数据
类型系统(Type System)
-
Schema的意义
- 对我们所需要的数据的确切描述
- 可以选择什么字段
- 服务器会返回那种对象
- 这些对象下有哪些字段可用
每个GraphQL服务都会定义一套类型,用以描述可能从服务查询到的数据
类型语言(Type Language)
- GraphQL服务,不依赖于任何特定语言的句法句式与GraphQL schema沟通
- GraphQL schema language与GraphQL的查询语言类似,用来与GraphQL schema之间沟通
对象类型和字段(Object Types and Fields)
- GraphQL schema 基本组件是对象类型
- 可从服务上获取到什么类型的对象
- 对象有什么字段
type Character {
name: String!
appearsIn: [Episode]!
}
对上述schema进行声明
- Character是一个GraphQL对象类型
- name、appearsIn是Character上的字段,在操作Character类型的GraphQL查询中,智能出现name、appearsIn字段
- String是内置的标量类型之一,标量类型是解析到单个标量对象的类型,无法在查询中对它进行次级选择
- !表示字段是非空的,GraphQL服务保证查询此字段总会返回一个值
-
[Episode]!
表示一个Episode
数组,非空。
参数(Arguments)
- GraphQL对象类型上,每一个字段都会有参数
- 所有参数都是具名的,所有参数必须具名传递
- 参数可能是 必选的 可选的
- 若参数可选,可以为其定义默认值
type Starship {
id: ID!
name: String!
length(unit: LengthUnit = METER): Float
}
查询和变更类型(The Query and Mutation Types)
- 特殊类型:
query
,mutation
- 定义了每一个GraphQL查询的入口
标量类型(Scalar Types)
- Int:有符号32位整数
- Float:有符号双精度浮点数
- String:UTF-8字符序列
- Boolean:true/false
- ID:表示一个唯一标示符,
自定义标量类型
scalar Date
- 定义其序列化、反序列化、验证
枚举类型(Enumeration Types)
- 枚举(enum),一种特殊的标量,限制在一个特殊可选集合内
- 可验证这个类型的任何参数是可选值的一个
- 与类型系统沟通,一个字段总是一个有限集合的其中一个值
enum Episode {
NEWHOPE
EMPIRE
JEDI
}
- 以上,表示,Episode返回后边三个值中的一个
列表和非空(Lists andNon-Null)
- 仅可自定的类型:对象类型、标量、枚举
- 可以对上述类型添加类型修饰符,来影响这些值的验证
type Character{
name: String!
appearsIn: [Episode]!
}
- 非空与列表类型修饰符的组合使用
-
myField: [String!]
,表示一个非空字符串的数组,表示数组可以空,但是数组每项不能空 -
myField: [String]!
,表示数组可以空,数组每项不能空
-
- 可根据需求,嵌套任意层非空、列表修饰符
接口(Interfaces)
- 一个接口是一个抽象类型,包含某些字段,对象类型必须包含这些字段,才能算实现了这个接口
interface Character {
id: ID!
name: String!
friends: [Character]
appearsIn: [Episode]!
}
- 以上接口,意味着,实现Character的类型要具有这些字段,并有对应参数和返回类型
联合类型(Union Types)
- 类似接口,单不指定类型之间的任何共同字段
union SearchResult = Human | Droid | Starship
- 上述表示,任何返回SearchResult类型的地方,可能得到Human/Droid/Starship。
- 联合类型成员必须是具体对象类型,不能使用接口或其他联合类型来创造一个联合类型
// 查询
{
search(text: "an") {
... on Human {
name
height
}
... on Droid {
name
primaryFunction
}
... on Starship {
name
length
}
}
}
// 结果
{
"data": {
"search": [
{
"name": "Han Solo",
"height": 1.8
},
{
"name": "Leia Organa",
"height": 1.5
},
{
"name": "TIE Advanced x1",
"length": 9.2
}
]
}
}
输入类型(Input Types)
- 用在变更中,很有用,比如,需要传递一个对象作为新建对象。
- 关键字input
input ReviewInput {
stars: Int!
commentary: String
}
- 使用的话
# 声明
mutation CreateReviewForEpisode($ep: Episode!, $review: ReviewInput!) {
createReview(episode: $ep, review: $review) {
stars
commentary
}
}
{
"ep": "JEDI",
"review": {
"stars": 5,
"commentary": "This is a great movie!"
}
}
{
"data": {
"createReview": {
"stars": 5,
"commentary": "This is a great movie!"
}
}
}