GraphQL学习——Schema和类型

  • 学习GraphQL类型系统
  • 类型系统如何描述可以查询的数据

类型系统(Type System)

  • Schema的意义

    • 对我们所需要的数据的确切描述
    • 可以选择什么字段
    • 服务器会返回那种对象
    • 这些对象下有哪些字段可用
  • 每个GraphQL服务都会定义一套类型,用以描述可能从服务查询到的数据

类型语言(Type Language)

  • GraphQL服务,不依赖于任何特定语言的句法句式与GraphQL schema沟通
  • GraphQL schema language与GraphQL的查询语言类似,用来与GraphQL schema之间沟通

对象类型和字段(Object Types and Fields)

  • GraphQL schema 基本组件是对象类型
    • 可从服务上获取到什么类型的对象
    • 对象有什么字段
type Character {
  name: String!
  appearsIn: [Episode]!
}

对上述schema进行声明

  • Character是一个GraphQL对象类型
  • name、appearsIn是Character上的字段,在操作Character类型的GraphQL查询中,智能出现name、appearsIn字段
  • String是内置的标量类型之一,标量类型是解析到单个标量对象的类型,无法在查询中对它进行次级选择
  • !表示字段是非空的,GraphQL服务保证查询此字段总会返回一个值
  • [Episode]!表示一个Episode数组,非空。

参数(Arguments)

  • GraphQL对象类型上,每一个字段都会有参数
  • 所有参数都是具名的,所有参数必须具名传递
  • 参数可能是 必选的 可选的
  • 若参数可选,可以为其定义默认值
type Starship {
  id: ID!
  name: String!
  length(unit: LengthUnit = METER): Float
}

查询和变更类型(The Query and Mutation Types)

  • 特殊类型:querymutation
  • 定义了每一个GraphQL查询的入口

标量类型(Scalar Types)

  • Int:有符号32位整数
  • Float:有符号双精度浮点数
  • String:UTF-8字符序列
  • Boolean:true/false
  • ID:表示一个唯一标示符,

自定义标量类型

scalar Date
  • 定义其序列化、反序列化、验证

枚举类型(Enumeration Types)

  • 枚举(enum),一种特殊的标量,限制在一个特殊可选集合内
    • 可验证这个类型的任何参数是可选值的一个
    • 与类型系统沟通,一个字段总是一个有限集合的其中一个值
enum Episode {
  NEWHOPE
  EMPIRE
  JEDI
}
  • 以上,表示,Episode返回后边三个值中的一个

列表和非空(Lists andNon-Null)

  • 仅可自定的类型:对象类型、标量、枚举
  • 可以对上述类型添加类型修饰符,来影响这些值的验证
type Character{
  name: String!
  appearsIn: [Episode]!
}
  • 非空与列表类型修饰符的组合使用
    • myField: [String!],表示一个非空字符串的数组,表示数组可以空,但是数组每项不能空
    • myField: [String]!,表示数组可以空,数组每项不能空
  • 可根据需求,嵌套任意层非空、列表修饰符

接口(Interfaces)

  • 一个接口是一个抽象类型,包含某些字段,对象类型必须包含这些字段,才能算实现了这个接口
interface Character {
  id: ID!
  name: String!
  friends: [Character]
  appearsIn: [Episode]!
}
  • 以上接口,意味着,实现Character的类型要具有这些字段,并有对应参数和返回类型

联合类型(Union Types)

  • 类似接口,单不指定类型之间的任何共同字段
union SearchResult = Human | Droid | Starship
  • 上述表示,任何返回SearchResult类型的地方,可能得到Human/Droid/Starship。
  • 联合类型成员必须是具体对象类型,不能使用接口或其他联合类型来创造一个联合类型
// 查询
{
  search(text: "an") {
    ... on Human {
      name
      height
    }
    ... on Droid {
      name
      primaryFunction
    }
    ... on Starship {
      name
      length
    }
  }
}

// 结果
{
  "data": {
    "search": [
      {
        "name": "Han Solo",
        "height": 1.8
      },
      {
        "name": "Leia Organa",
        "height": 1.5
      },
      {
        "name": "TIE Advanced x1",
        "length": 9.2
      }
    ]
  }
}

输入类型(Input Types)

  • 用在变更中,很有用,比如,需要传递一个对象作为新建对象。
  • 关键字input
input ReviewInput {
  stars: Int!
  commentary: String
}
  • 使用的话
# 声明
mutation CreateReviewForEpisode($ep: Episode!, $review: ReviewInput!) {
  createReview(episode: $ep, review: $review) {
    stars
    commentary
  }
}
{
  "ep": "JEDI",
  "review": {
    "stars": 5,
    "commentary": "This is a great movie!"
  }
}
{
  "data": {
    "createReview": {
      "stars": 5,
      "commentary": "This is a great movie!"
    }
  }
}

推荐阅读更多精彩内容