GraphQL 第二章 Schema 和类型

本文深入解析GraphQL中的Schema和类型系统,涵盖对象类型、标量类型、枚举类型、接口、联合类型及输入类型等关键概念,助你全面理解GraphQL数据查询语言。

GraphQL 第二章 Schema 和类型

定义了 schema 后我们就能知道服务器会返回那种对象,这些对象有哪些字段可用等。
每个 GraphQL 服务都会定义一套类型,用以描述你可能从那个服务查询到的数据,每当查询到来,服务器就会根据 schema 验证并执行查询。
之前我们讲了 GraphQL 的查询语言,这里我们来讲一下 GraphQL Schema language 。这个和 GraphQL 的查询语言类似。

一个 GraphQL schema 中的最基本的组件是对象类型,它表示你可以从服务上获取到什么样类型的对象,以及对象的字段。

type Human {
	name: String!
	height: Float
	friends: [Person!]!
}

这里我们定义了一个 Human 对象类型,这个对象中包括了几个字段。 String Float 是内置的标量类型,String! 表示这个字段是非空的,[person!]! 表示一个 person 数组,他也是非空的,所以当你查询 friends 时能得到一个数组,并且由于 Person!也是非空的,所以你可以得到的数组中每个项目都是一个 Person 对象.

GraphQL 对象类型上的每个字段都有可能有 0 或 多个参数

这里所有的参数都是具名的

type Human {
	name: String!
	height:(unit: HeightUnit = METER) Float
	friends:[Person!]!
}

Schema 中有两个特殊的类型 Query 和 Mutation 。

schema {
	query: Query
	mutation: Mutation
}

每个 GraphQL 服务都有一个 query 类型,可能有一个 mutation 类型。这两个类型和常规对象类型无差,但是它们之所以特殊,是因为它们定义了每一个 GraphQL 查询的入口,这也是它们唯一特殊的地方,别的与普通对象类型无二致。

query {
	hero { name }
	person(id: 1) { name}
}
# -------->
type Query {
	hero: Charactor
	person(id: ID!): Charactor
}

标量类型(scalar type)

在之前我们就用到过好多次String Float 这些类型了,这些类型叫做标量类型,这些类型是没有次级字段的,对象类型是有次级字段的。
GraphQL 自带一组默认标量类型:
* Int:有符号 32 位整数。
* Float:有符号双精度浮点值。
* String:UTF‐8 字符序列。
* Boolean:true 或者 false。
* ID:ID 标量类型表示一个唯一标识符,通常用以重新获取对象或者作为缓存中的键。ID 类型使用和 String 一样的方式序列化;然而将其定义为 ID 意味着并不需要人类可读型。
我们还可以自定义标量类型,取决于我们的实现中如何定义将其序列化、反序列化和验证。

scalar Date
# 例如定义一个Date 类型应该总是被序列化成整形时间戳,而客户端应该知道去要求任何 date 字段都是这样的格式

枚举类型(enumeration type)

这个其实和别的语言中的枚举类型是差不多的。枚举类型是一种特殊的标量,它限制在一个特殊的可选值集合内。
1. 验证这个类型的任何参数是可选值的某一个
2. 与类型系统沟通,一个字段总是一个有限值集合的其中一个值

enum Hobby {
	swim
	football
	basketball
}

类型修饰符

我们之前就已经看到过两个了,分别是 ! [] 一个是用来标注 非空 ,一个是标注 数组
标记了非空的字段,服务器总会返回一个非空值,如果它得到一个空值,就会触发一个 GraphQL 执行错误。如果定义的参数有这个非空标识,传参时给个空值,会导致服务器返回一个验证错误。
列表就相对来说直观些了,通过[] 定义的就是一个数组了

接下来我们来看看这两者结合使用的情况

myField: [String!]
# ------------- #
myField: null # 有效
myField: [] # 有效
myField: ['a','b'] # 有效
myField: ['a',null,'b'] # 错误
myField: [String]!
# ------------ #
myField: null # 错误
muField: [] # 有效
myField: ['a','b'] # 有效
myField: ['a',null,'b'] # 有效

结口(Interface)

GraphQL 支持接口,一个接口是一个抽象类型,它包含某些字段,而实现这个接口的对象类型必须包含这些字段

interface Human {
	id: ID!
	name: String
	age: Int
	height: Float
	friends:[Person!]!
}

实现 Human 接口

type Female implements Human {
	id: ID!
	name: String
	age: Int
	height: Float
	friends:[Person!]!
	feature: [String!]
}

type Male implements Human {
	id: ID!
	name: String
	age: Int
	height: Float
	friends: [Person!]!
	hobby: [String!]
}

联合类型(Union type)

联合类型和接口十分相似,但是它并不指定类型之间的任何共同字段,联合类型的成员需要是具体对象类型,你不能使用接口或者其他联合类型来创建一个联合类型。

union searchResult = Human | Hero | Person

输入类型(input type)

我们之前传递的参数都是一些标量类型或者是枚举类型的值,但是我们不可避免的会传递一些复杂对象,比如在新增、更新操作中,这时候就引入了输入对象类型,它和常规对象一样,只是关键字是 input 而不是 type

input person {
	name: String
	age: Int
	...
}
mutation createPerson($person: Person){
	createOne(one: $person){
		name
		age
	}
}
# ---------- #
# person 
{
		name:'zs',
		age: 10
}

输入对象类型上的字段本身也可以指代输入对象类型,但是你不能在你的 schema 混淆输入和输出类型。输入对象类型的字段当然也不能拥有参数。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值