GraphQL的学习笔记(一)


2019-3-17 GraphQL

GraphQL 的学习笔记(一)

学习过程中资料来源

  1. GraphQL 中文网
  2. GraphQL 中文版教程
  3. GraphQL TODO

GraphQLhe restful 区别

  • 扩展性高
  • 不通过 url 来区别资源而是用类型来区分资源
  • 一次可以获取多个资源
  • 一般情况下是单一入口而不是多 url 请求路径

graphql 的基础知识

基础类型

graphql 有五种数据基本类型:

String 默认 utf-8 int 32 位 float 双精点浮动 boolean 和 id ,id 本质是字符串类型 但是是不可以重复的 ,这几个类型在 schema 直接声明然后使用,数组用[].

自定义的标量类型,

scalar 类型 这种自动的标量类型可以当作基础类型使用,但是要自定义其序列化和反序列化以及验证的规则 如何进行序列化和反序列化

枚举类型

enum 限制在可选级中 enum 集{参数}

对象类型

type 对象名称(首字母大写) 对象类型定义了一个查询或输入的总体格式

代表不许输入或者必须输出,必须存在

参数类型

graphql 中所有的传递的参数都是具名的,参数在传递过程中可以设置默认值,

length(unit:lengthUnit = meter) 表示当参数类型是 unit 当没有传递的时候默认为 meter

特殊定义的类型

1 查询类型 query 2 变更类型 mutation 在 graphql 中查询类型必须存在,如果不存在则这个 graphql 不可以使用。 mutation 对应输入类型 input 而不是 type

接口 interfaces

一个接口是一个抽象类型,包含了某些字段 对象必须实现某些字段才能实现这个接口

  • 定义接口 interfaces 接口名称{接口中的字段以及规则}
  • 实现接口 type 实体 implements 接口 {接口字段,自定义字段}
  • 接口类型主要使用在当需要返回一个对象,多个对象或者对象时不同的类型的时候
  • 查询的时候对应内联片段

联合类型

联合类型和接口类型但是不指定任何片段 定义方法 union 类型名称 = 类型一|类型 2|类型三 使用这个联合类型后返回的时一个类型 1 类型 2 或者类型 3,查询时需要使用--条件片段查询

别名

aliases 在前端定义查询的时候,如果遇到在一个查询内部多次查询一个查询属性这个时候会引发冲突,需要使用别名来定义,具体使用方式就像 js 中给方法定影上方法名类似 别名:需要调用的方法(参数名:参数值){需要的返回值}

查询片段

可定义一个可复用的查询单元(返回值类型集合),定义方法,

fragment comparisonFields on Character {
    # 需要的返回值 列在这里
}
# 使用的时候,解构赋值
在查询方法内部 ...comparisonFields

1
2
3
4
5
6

操作类型

query mutation subscription

变量

variables 使前端使用时字段的参数变为动态 {“graphql”:true,“variables”:{“episode”:jedi}} 变量不必须是标量类型,对象类型 或是枚举类型

指令

directives @include (if:boolean)仅在参数位 true 的时候包含此字段 @skip(if:boolean)仅仅在参数位 true 的时候跳过此字段,用于在查询的时候增减字段,灵活的定义字段

变更 Mutations

mutations 方法名($函数名后端:函数名本地,$函数名后端:函数名本地){
    后端的方法名(后端参数名:$函数名后端,后端参数名:$函数名后端){
        需要的返回值
    }
}
 variables{"graphql":true,"variables":{前端的参数名:前端的参数值}}
1
2
3
4
5
6

变更多个字段

一个变更可以操作多个字段 但是变更字段是线性的 一个接一个查询时并行的,如果同时又两个同名的变更会先执行第一个确保不会出现竞争状态。

内联片段

如果查询的字段返回的是接口或者联合类型 需要使用联合片段取出具体的数据。

# 使用 ...on 查询的对象 来确定查询的结果
query HeroFOrepisode($ep:Episode!){
    hero(episode:$ep){
        name
        ...on Droid{
                primaryFuntion
            }
        ...on Human{
        height
        }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12

意思是如果请求的参数在后台查询过程收纳柜是 Droid 类型则返回 primaryFuntion 反之则返回 height

原字段

如果不知道服务返回什么类型 这个时候由客户端决定是个什么数据,可以从 graphql 的内省系统中使用一些变量,可以对返回的接口经行验证和判断。

_ _schema 返回哪些类型可以使用

_ _typeName 获取对象的名称 name---对应这个

_ _type 鉴定类型

_ _ typeKind 对象类型 由 kind ---对应这个

__field 查看字段 fields 对应这个

__inputValue 要求的输入参数

__EnumValue

__Directive

可以指定的属性 name kind description fields ofType 等等

生产模式

推荐在生产环境下使用压缩格式 gzip Accept-Encoding:gzip

分页

服务端诗句使用 数组,在请求的时候,参数内部可以定义类似 first after offset 等等,

具体实现

  • 第一种分页 friends(first:20 offsert:20) 表示第一次请求 20 个 接下来每次都略过 20 个

  • 第二种分页 friends(first:20 after:$friendsID)friendsID 是上次请求的最后一个朋友的 ID

  • 第三种分页friends(frist:20 after:$friendCursor)从左后一页获取一个游标来进行分页,使用这种分页更加强大,但是需要设计游标,而游标则表示总体数量和当前位置并且把数据放置在游标内部,游标充当整体数据的边界和定位位置。具体实现

    hero{
        name
        friends(first:2 after:上一页最后一个指针){
            totalCount#总数
            edges{#边界
                node{#节点
                    name
                }
                  cursor# 指针 自己定义的
            }
            pageInfo{
                endCursor#最后一个光标是什么
                hasNextPage#还有没有下一页
            }
        }
    }
    # 在后端的代码种页要定义同样的方法  并且做好整体查询以及生成指针的操作
    
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18