一、什么是GraphQL

GraphQL 是Facebook开发的API查询语言,而不是一个数据库。

GraphQL 是基于API之上的一层封装,目的是为了更好,更灵活的适用于业务的需求变化。

GraphQL 是一套API规范,只要按照规范设计,它可以运行在任何后端框架或者编程语言之上。

二、为什么使用GraphQL

三、基本概念

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 自带一组默认标量类型:

自定义标量

sclar Date

除了标量类型还有枚举、列表和非空、接口interface、联合类型、输入类型等

输入对象看上去和常规对象一模一样,除了关键字是 input 而不是 type,输入对象类型的字段当然也不能拥有参数。

类型系统除了可以让我们清楚的了解获取的数据类型,也可以在请求数据类型出错时,触发一个 GraphQL 执行错误,以让客户端知道发生了错误。而不需要后端去处理这种类型错误

优点