基础介绍
1、什么是GraphQL
GraphQL是一个用于API的查询语言,是一个使用基于类型系统来执行查询的服务端运行时。
2、优点:(其实就是优化了RESTful API)
1)可以限制应该从服务器获取的数据,只获得你想要的东西
比如有一个业务对象 Student ,其属性为 id,firstName,lastName 和 collegeName。
假设我们只想要获取 firstName 和 id。如果设计了一个REST端点(/api/v1/students ),它将最终获取 student 对象的所有字段的数据。而GraphQL(如下格式查询)只会返回对应需要的。
{
students {
id
firstName
}
}
这样仅仅只会反映所需的字段
{
"data": {
"students": [{
"id": "S1001",
"firstName": "Mohtashim"
}, {
"id": "S1002",
"firstName": "Kannan"
} ]
}
}
2)在单个请求中获取所需的所用数据(检索关联数据时)
比如有关联的两个业务对象学生和大学,我想查询到学生以及对应的大学详细信息。REST需要两个接口而GraphQL只需要单个请求。
{
students{
id
firstName
college{
name
location
}
}
}
输出:
{
"data": {
"students": [ {
"id": "S1001",
"firstName": "Mohtashim",
"college": {
"name": "CUSAT",
"location": "Kerala"
}
},{......} ]
}
}
3)描述类型系统的可能性
API基于类型和字段的方式进行组成,使用类型来保证应用只请求可能的类型。当GraphQL查询中存在类型不匹配。会返回清晰的辅助性错误信息。
type User {
name: String
age: Int
}
type Query {
hero: String
user: User(User对应上面的type)
重要概念
1)Schema:模式
每一个GraphQL服务都会定义一套类型,用以描述你可能从那个服务器查询到的数据。每当查询出来,就会根据schema验证并执行查询。
介绍:Schema由服务端来定义,用于定义API接口,并依靠Schema来生成文档以及对客户端进行校验。(只是一个概念)
操作类型:
-
query: 这个关键字属于schema中的一种,代表你要执行的是查询动作。
-
mutation: 代表你要执行的动作是增删改
-
substription 订阅:当数据发生更改,进行消息推送
注意:
在 Query 查询字段时,是并行执行的,而在 Mutation 变更的时候,是线性执行,一个接着一个,防止同时变更带来的竞态问题,
比如说我们在一个请求中发送了两个 Mutation,那么前一个将始终在后一个之前执行。
2)对象类型和字段
对象类型:用户在schema中定义的type
注意:
- 一个schema的基本组成就是对象类型,它表示可以从服务器上获取到什么类型的对象以及对应的属性字段。
- 一个GraphQL 服务接受到了一个query,从rootQuery开始查找,当找到对应的对象类型时则使用它的解析函数Resolver来获取内容,如果返回的是对象类型则继续解析,如果是标量类型则结束获取,直到找到最后一个标量类型。
#国家对象
type Country{
#国家名称
name: String
#省份
province: String
}
- “ # ” 号:注释
- “Country”:表示GraphQL的对象类型。与Java对象类似
- “name”、“province”:对象类型上的字段,“ :”后跟的是内置的标量类型
3)标量类型: - Int:有符号 32 位整数。
- Float:有符号双精度浮点值。
- String:UTF‐8 字符序列。
- Boolean:true 或者false。
- ID:常用于获取数据的唯一标志。
4)集合:使用 “ [ ] ”来标记一个类型为集合
#国家对象
type Country{
#国家名称
name: String
#省份
province: [String]
5)空和非空:在类型后添加 “ !” 标注其为非空
#国家对象
type Country{
#国家名称
name: String!
#省份
province: [String!]
#市
city:[String!]!
}
- String! 表示当前name字段非空。
- [String!] 表示province的返回值是一个非空字符串的数组(集合)。
即数组本身可以为空,但是其不能有任何空值成员。
province: null // 有效
province: [] // 有效
province: ['a', 'b'] // 有效
province: ['a', null, 'b'] // 错误
- [String!]! 表示city的值是一个、非空字符串的非空数组(集合)。
即返回的集合不能为空,集合中也不能存在空值。
city: null // 错误
city: [] // 错误
city: ['a', 'b'] // 有效
city: ['a', null, 'b'] // 错误
6)参数:前端提交查询请求时,可能需要传id等参数进行精确查询。
type query{
#需要传入的参数信息
dwxx(
#单位代码,必填
dwdm:String!
#单位名称
dwmc:String
):Dwxx
}
type Dwxx{
id:Int
..
# 查询返回的单位对象类型的一些属性字段
}
7)Resolver:解析函数
GraphQL对于每个字Query和与之对应的REsolver有明确的定义规范,以确保GraphQL能把Schema中每个子query同他们的Resolver一一对应起来。最终实现后端逻辑处理数据后丢给Graphql最终返回给前端。
< fieldname >(dataRepositoryClassInstance, *fieldArgs [, DataFetchingEnvironment])
is< Fieldname >(dataRepositoryClassInstance, *fieldArgs [, DataFetchingEnvironment])
get< Fieldname >(dataRepositoryClassInstance, *fieldArgs [, DataFetchingEnvironment])
getField< Fieldname >(dataRepositoryClassInstance, *fieldArgs [, DataFetchingEnvironment])
参考资料:
GraphQL 入门:实现前后端分离