GraphQL Spec / GraphQL 标准概览

GraphQL Spec / GraphQL 标准概览

本篇基于 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 {
  version: String
}

Client:

query {
  version
}

变动 Mutation

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

Schema:

type User {
  name: String
}

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

Client:

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

基本类型 Scalars

  • Int
  • Float
  • String
  • Boolean
  • ID

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

ID 可以是 String 类型,也可以是 Int 类型,它不是为了可读性,只是为了提供了一种多变的类型

对象 Objects

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

Schema:

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

字段查询 Field Query

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

Schema:

type Person {
  name: String
  pictures(size: Int): [String]
}

Client:

query {
  user {
    name
    pictures(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,和编程语言中 Extension 是一样的功能

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 {
  business(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
      age
    }
    ... on Photo {
      height
      width
    }
  }
}

枚举 Enums

Enum 即枚举类型,无需多言

Schema:

enum Direction {
  NORTH
  EAST
  SOUTH
  WEST
}

输入对象 Input Objects

Input Objects 为组织字段的结合体,可以组织一些字段成为一个集合结构,这样可以对字段进行约束和规范,且应只使用于 Mutation,Query 不应使用 Input

Schema:

input CreatePoint2DInput {
  x: Float
  y: Float
}

type Mutation {
  createPoint2D(input: CreatePoint2DInput)
}

列表 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)
}

Pagination Guideline 分页规范

GraphQL 中的建议分页规范是使用基于 Cursor(游标) 的分页方式

Schema:

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

type StudentEdge {
  cursor: String!
  node: Student
}

type PageInfo {
  hasNextPage: Boolean!
  hasPreviousPage: Boolean!
  startCursor: String!
  endCursor: String!
}

type StudentConnection {
  edges: [StudentEdge]
  nodes: [Student] // Optional use
  pageInfo: PageInfo!
  totalCount: Int!
}

type Class {
  students(first: Int, after: String, last: Int, before: String): StudentConnection
}

参数作用

参数一般为 first & after 或 last & before 配合使用

first: 从前到后取出的数量
after: 从前到后开始取值的游标位置

last: 从后到前取出的数量
before: 从后到前开始取值的游标位置

粤ICP备2022080316号-1
粤公网安备 44030902003469号