本篇基于 2018 六月份 发布的版本

简介 Overview


GraphQL 来自于 Facebook,Facebook 从 2012 年开始构思,在 2015 年正式发布开源

GraphQL 由两部分组成: (GraphQL) Query Language(GraphQL) Engine,就如 SQLDatabase 一样的关系,只不过 GraphQL 在 API 架构上表达了这种设计模式

客户端方一样需要发送请求至后端方,方式可以是 HTTP 亦或 WebSocket,只不过请求体本身的介质是 Query Language

后端方定义了整个 Engine 的所有类型和数据操作方式,而这个整体的表达称为 Schema

类型系统 Type System


以下的内容是表现在 Schema 上的

查询 Query

每个 Schema 都必须拥有一个顶级类型,那就是 Query,Query 即代表了查询数据的方式

Schema:

type Query {
  myName: String
}

Client:

query {
  myName
}

变动 Mutation

Mutation 是可选的,当需要对数据进行操作的话,是需要编写 Mutation 来进行的

Schema:

type User {
  name: String
}

Client:

type Mutation {
  setName(name: String): User
}

mutation {
  setName(name: "Zuck") {
    name
  }
}

基本类型 Scalars

  • Int
  • Float
  • String
  • Boolean
  • ID

前四个就不需要过多描述了,而 ID 这个类型,字面意思上也肯定知道是用作 ID 的,但是同时可能就会有一些疑问,用 IntString 不都可以用作 ID 么,ID 这个类型不就很多余么?

IDString 在本身上没有什么很大的区别,它只能是 String, 所以在赋值前,不管元数据是什么类型,都要序列化为 String 并且需要是唯一的,ID 真正的作用是 缓存,GraphQL Engine 会在重新获取对象的时候通过 ID 进行缓存

对象 Objects

对象非常简单理解,就是字面意思,它包含了一系列的字段,而这些字段一般都是由 Scalar 和其他类型组成

Schema:

type Person {
  name: String
  age: Int
  picture: Url
}

字段查询 Field Query

让某一个字段变成 Query,这样可以更加形象的描述 Object 和 Query 之间的上下关系结构

Schema:

type Person {
  name: String
  picture(size: Int): Url
}

Client:

query {
  user {
    name
    picture(size: 10)
  }
}

弃用字段 @deprecated

在某一个字段后面添加 @deprecated,即代表这个字段为弃用状态

Schema:

type ExampleType {
  oldField: String @deprecated
}

并且可以给 @deprecated 添加 reason 字段,用以描述 弃用理由

Schema:

type ExampleType {
  oldField: String @deprecated(reason: "Reason description")
}

对象扩展 Object Extensions

对象扩展就是对现有的 Object 进行扩展,而无需增加一个新的 Object

Schema:

extend type Story {
  isHiddenLocally: Boolean
}

接口 Interfaces

Interface 由一系列的字段组成,定义了一种实现协议,当某个 Object 实现了一个 Interface,那么就需要实现这个 Interface 里面的所有字段

Schema:

interface NamedEntity {
  name: String
}

interface ValuedEntity {
  value: Int
}

type Person implements NamedEntity {
  name: String
  age: Int
}

type Business implements NamedEntity & ValuedEntity {
  name: String
  value: Int
  employeeCount: Int
}

Client:

query {
  businesses(name: "business_name") {
    name
    value
    employeeCount
  }
}

联合 Unions

Union 是多个类型并集成一个类型,而这个类型可以拥有多个类型的性质,但是它在 Runtime 只能是其中一个类型

Schema:

union SearchResult = Photo | Person

type Person {
  id: ID
  name: String
  age: Int
}

type Photo {
  id: ID
  height: Int
  width: Int
}

type SearchQuery {
  firstSearchResult: SearchResult
}

Client:

{
  firstSearchResult {
    id
    ... on Person {
      name
    }
    ... on Photo {
      height
    }
  }
}

枚举 Enums

Enum 即枚举类型,无需多言

Schema:

enum Direction {
  NORTH
  EAST
  SOUTH
  WEST
}

输入对象 Input Objects

Input Objects 为组织字段的结合体,可以组织一些字段成为一个集合结构,这样可以对字段进行约束和规范

Schema:

input Point2D {
  x: Float
  y: Float
}

列表 List

List 即集合类型,正如编程语言中的 List 作用一样,包含一系列同样类型的元素

Schema:

type Students {
  id: ID
  name: String
  age: Int
}

type Class {
  students: [Students]
}

Fragments 片段

Fragment 主要存在于 Client 方的 Query Language 中

query withFragments {
  user(id: 4) {
    friends(first: 10) {
      ...friendFields
    }
    mutualFriends(first: 10) {
      ...friendFields
    }
  }
}

fragment friendFields on User {
  id
  name
  profilePic(size: 50)
}