Graphql学习(三)-Schema和类型

这一篇介绍一下构建GraphQL的类型及定义,会被GraphQL整体结构有个大致的了解
为了能够准确描述每一个查询会返回的结果、对象、字段,故引入了Schema。
Schema的主要用途是定义所有可供查询的字段(field),它们最终组合成一套完整的GraphQL API.

类型系统

每一个GraphQL服务都会定义一套类型,来描述服务可能返回的所有数据。当执行一个查询时,服务会根据定义的Schema验证并执行查询。

类型语言

GraphQL 服务可以用任何语言编写,因为我们并不依赖于任何特定语言的句法句式(譬如 JavaScript)来与 GraphQL schema 沟通,我们定义了自己的简单语言,称之为 “GraphQL schema language” —— 它和 GraphQL 的查询语言很相似,让我们能够和 GraphQL schema 之间可以无语言差异地沟通。

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

对象类型定义:

1
2
3
4
5
type Person{
  name:String!
  age:Int
  dpgs:[dog]!
}

 

  • Person是一个GraphQL对象类型,表示一个拥有一些字段的类型,类比于Java的Class
  • name和age是Person类型上的字段,代表在Person类型中的查询只能有name和age
  • String!是内置变量,!代表非空
  • dogs代表是一个dog类型的数组,也可以用非空表示

参数(Arguments)

可以在对象类型的字段上定义参数,比如

1
2
3
type Person{
  weight:(unit:weightUnit=KG):Int
}

 

weight定义一个参数unit,可以定义一个默认值,当查询没有传递时,会被设置为KG

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

Schema里除了普通的对象类型外,有2个特殊类型:

1
2
3
4
schema {
  query: Query
  mutation: Mutation
}

 

这2个类型定义了每一个GraphQL查询的入口,如下一个查询

1
2
3
4
5
query{
  person(id:"2222"){
    name
  }
}

 

标识这个GraphQL服务需要一个Query类型,并且有person字段:

1
2
3
type Query{
  person(id: ID): Person
}

 

同样的变更(Mutation)操作也类似。

标量类型(Scalar Types)

一个对象类型有自己的名字和字段,这些字段在一定情况下回解析到具体数据。这就是标量类型的来源:表示对应GraphQL查询的叶子节点。标量类型没有次级字段,是整棵查询树的叶子节点。后面会提到,查询字段数据的执行器直到遇到标量类型才会停止继续下挖。
GraphQL自带一组默认标量类型:

  • Int、Float、String、Boolean 都与其他语言雷同
  • ID:代表一个唯一标识符,序列化方式与String一致
    我们可以使用GraphQL服务自定义标量类型,比如Date类型
    scalar Date,实现中需要保证序列化、反序列化、验证方式都是可逆的

其他类型

  • 枚举 enum
  • 列表和为空 [xxx] !
  • 接口(Interfaces):类比Java的interface,一个抽象类型,包含某些字段可以被实现
    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    interface animal{
      id:ID!
      name:String
    }
    type human implements human{
      id:ID!
      name:String
      think:String
    }
    

当要返回一组对象,但类型不同时,可以使用,但需要配合内联片段(…)。

  • 联合类型(union search = Male|Female|Child)可以返回对象类型的组合
  • 输入类型(Input Types)
    有时候你需要在mutation操作中传入一个复杂对象,比如在Rest API中常用的json对象。输入对象看上去和常规对象一样,只是关键字不同
    1
    2
    3
    4
    
    input ActInput{
      actId:Int
      actName:String!
    }
    

你可以在变更操作中使用Input Type

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
mutation createAct($act:ActInput!){
  create(act:$act){
    actId
    actName
  }
}
Variable:
{
  "actId":123,
  "actName":"asdsadsa"
}
{
  "data":{
    "create":{
      "actId":123,
      "actName":"asdsadsa"
    }
  }
}

 

在schema中不能混淆输入与输出对象类型。

验证

当我们查询一个字段时,如果该字段的返回值不是标量类型或者枚举类型,那么我们就需要显示的指名需要从这个字段中获取的具体数据。

1
2
3
{
  person
}

 

person是一个对象类型,如果不指名其中的name或者其他标量类型字段,这个查询就是无效的。

1
2
3
4
5
6
7
8
9
10
11
12
13
{
  "errors": [
    {
      "message": "Field \"person\" of type \"Person\" must have a selection of subfields. Did you mean \"person { ... }\"?",
      "locations": [
        {
          "line": 3,
          "column": 3
        }
      ]
    }
  ]
}

 

整体来说,GraphQL的验证规则及语义十分繁琐,这方面的问题可以在实际使用中再去深入了解

总结

这一章简单介绍了Schema的创建及一些GraphQL中的基础类型,为后续服务端编写提供了基础

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值