一、什么是GraphQL
GraphQL 是Facebook开发的API查询语言,而不是一个数据库。
GraphQL 是基于API之上的一层封装,目的是为了更好,更灵活的适用于业务的需求变化。
GraphQL 是一套API规范,只要按照规范设计,它可以运行在任何后端框架或者编程语言之上。
二、为什么使用GraphQL
即使提前跟后端沟通好接口数据字段,实际开发过程中还是会发生接口少字段或多字段
多端公用一套数据接口时,数据冗余度高
前端的快速产品迭代对API有很大的挑战,改动成本很高
GraphQL 查询能够遍历相关对象及其字段,使得客户端可以一次请求查询大量相关数据,而不像传统 RESTful API 架构中那样需要多次往返查询。
三、基本概念
- 字段(Fields)
- 参数(Arguments)
- 操作名称(Operation name)
- 变量(Variables)
1、字段
Field是我们想从服务器获取的对象的基本组成部分。
// 查询语句
{
hello
todolist{
id
}
}
// 查询结果
{
"data": {
"hello": "hello world",
"todolist": [
{
"id": "1"
},
{
"id": "2"
}
]
}
}
可以看到查询和其结果拥有一样的结构,这是 GraphQL 最重要的特性,需要什么数据就拿什么数据。
todolist 返回了一个数组的项目,GraphQL 查询会同等看待单个项目或者一个列表的项目,具体通过 schema 决定
2、参数
字段可以传递参数,参数是可选的
// 查询语句
{
hello(name:"GraphQL")
todolist{
id
}
}
// 查询结果
{
"data": {
"hello": "hello GraphQL",
"todolist": [
{
"id": "1"
},
{
"id": "2"
}
]
}
}
在RESTful API 的系统中,你只能传递一组简单参数。但是在 GraphQL 中,每一个字段和嵌套对象都能有自己的一组参数,从而使得 GraphQL 可以完美替代多次 API 获取请求。
// 查询语句
{
hello(name:"GraphQL")
item(id:2){
id,
item_name,
status
}
}
// 查询结果
{
"data": {
"hello": "hello GraphQL",
"item": {
"id": "2",
"item_name": "GraphQl入门",
"status": true
}
}
}
需要注意的是,GraphQL中的字符串需要包装在双引号中。
3、操作名称
类似函数的名称,使你的操作的有意义和明确的名称
不写默认为query查询
操作类型的关键字 query 以及操作名称 list
// 查询语句
query list{
todolist{
id,
item_name,
status
}
}
// 查询结果
{
"data": {
"todolist": [
{
"id": "1",
"item_name": "深入理解TypeScript",
"status": false
},
{
"id": "2",
"item_name": "GraphQl入门",
"status": true
}
]
}
}
操作名称可以使我们代码减少歧义,方便查错和调试,开发中建议强制书写。
注意:使用查询简写语法的情况下,你无法为操作提供名称或变量定义。
4、变量
使用变量来让参数可动态变化,变量以$开头书写
query hello($name: String!) {
hello(name: $name)
}
参数可以拥有默认值:
query hello($name: String! = "world") {
hello(name: $name)
}
四、操作类型
GraphQL的三种操作类型Query、Mutation、Subscription
Query (查询)
query是GraphQL 中的获取数据的方式,需要什么数据获取什么数据
Mutation (变更、增删改)
更改是修改服务器上的数据并获取更新数据的方式
mutation被用以执行写操作,通过mutation我们会给服务器发送请求来修改和更新数据,并且会接收更新的数据。
// 修改
mutation updata{
updateItem(id: 3, item_name: "小程序IM", status: true) {
id
item_name
status
}
}
// 返回
{
"data": {
"updateItem": {
"id": "3",
"item_name": "小程序IM",
"status": true
}
}
}
为了保证数据的完整性mutation是串形执行,而query可以并行执行。
Subscription (订阅)
实时通信业务的需求,可以实现服务端对客户端的实时数据传递
subscription {
todolist {
id
item_name
status
}
}
五、Schema(模式)
描述可以查询到的数据的结构
type TodoItem {
id: ID!
item_name: String!
status: Boolean!
}
type Query {
hello(name:String = "world"): String
todolist: [TodoItem!]!
item(id: ID!): TodoItem!
}
type Mutation {
createItem(id: ID!, item_name: String!, status: Boolean!): TodoItem!
updateItem(id: ID!, item_name: String, status: Boolean!): TodoItem!
deleteItem(id: ID!): TodoItem!
}
!表示非空 ,[] 列表类型,也就是数组
每一个 GraphQL 服务都会定义一套类型,用以描述你可能从那个服务查询到的数据。每次查询,服务器就会根据 schema 验证并执行查询。
六、Type(类型)
类型是 GraphQL 最重要的特性之一
对象类型
type TodoItem {
id: ID!
item_name: String!
status: Boolean!
}
标量类型(Scalar Types)
GraphQL 查询的叶子节点,没有任何次级字段,类似js中的基本类型
GraphQL 自带一组默认标量类型:
- Int:有符号 32 位整数。
- Float:有符号双精度浮点值。
- String:UTF‐8 字符序列。
- Boolean:true 或者 false。
- ID:ID 标量类型表示一个唯一标识符,通常用以重新获取对象或者作为缓存中的键。ID 类型使用和 String 一样的方式序列化;然而将其定义为 ID 意味着并不需要人类可读型。
自定义标量
sclar Date
除了标量类型还有枚举、列表和非空、接口interface、联合类型、输入类型等
输入对象看上去和常规对象一模一样,除了关键字是 input 而不是 type,输入对象类型的字段当然也不能拥有参数。
类型系统除了可以让我们清楚的了解获取的数据类型,也可以在请求数据类型出错时,触发一个 GraphQL 执行错误,以让客户端知道发生了错误。而不需要后端去处理这种类型错误
优点
- 网络开销低,可以在单一请求中获取REST中使用多条请求获取的资源
- 强类型Schema(约束意味着可以根据规范形成文档、IDE、错误提示等生态工具)
- 特别适合图状数据结构的业务场景(比如好友、流程、组织架构等系统)

