GraphQL查询规范

司马渝
2023-12-01

什么是GraphQL

GraphQL是Facebook开发的一套查询语言,和Restful查询规范一样,都是一种对前后端数据交互的一种规范,并不是SQL这种的查询语言。

GraphQL和Restful区别

  • Restful:主流的前后端交互规范,并且开发的过程中,简洁明了,可以很方面的理解接口的含义,不会带来额外的开发的复杂度,但是接口的返回的数据是固定的,如果前端只需要部分数据,那么接口返回的还是全部的数据,会带来额外的资源浪费
  • GraphQL:主要是解决了Restful规范中问题,接口返回的数据不可控制,GraphQL的理念是让前端控制接口数据的字段的返回,让接口的灵活性增加,并且接口数据的增加和改变,不用带来接口的升级,维护多套接口,但是相对于Restful来讲,较为复杂

GraphQL查询规范

GraphQL定义了一套查询规范,可以让前端来控制需要查询的数据,灵活的控制查询的属性对象,仅仅是一种规范

常用的查询规范:

字段(Fileds)

在GraphQL的查询中,请求结构体中包含了锁预期结果的结构,这个就是字段。响应的数据的结构体保持和请求的结构体一致

  • 语法

    语法看起来和JSON有些类似,不过是自定义的查询的语言,可以自定义查询的对象或者字段

    {
    	hero {
    		name
        	id
    	}
    }
    
    // response
    {
        "data": {
            "hero": {
                "name": "xx",
            	"id": 1
            }
        }
    }
    
    • hero表示定义查询的对象,所以hero中的字段需要定义到hero的对象中
    • name表示查询的字段,hero对象的name字段
参数(Arguments)

GraphQL查询中,也可以携带参数,传递参数到服务端进行数据的查询

  • 语法

    {
    	hero(id: 11) {
    		name
    	}
    }
    
    // response
    {
        "data": {
            "hero": {
                "name": "xx"
            }
        }
    }
    
    • 通过在对象的后端加上**(),在()**中定义的字段会作为参数进行传递
别名(alias)

如果一次需要查询多个对象,那么需要为每个对象定义别名,否则返回的数据在解析JSON的过程中就会出现问题

  • 语法

    {
    	GaiHero: hero(id: 11) {
    		name
    	}
    	JaxHero: hero(id: 22) {
    		name
    	}
    }
    
    // response
    {
        "data": {
            "GaiHero": {
                "name": "gailun"
            },
            "JaxHero": {
                "name": "jax"
            }
        }
    }
    
    • GaiHerojaxHero表示为hero对象定义的别名,在返回的JSON数据中,字段的属性名称也是别名的名称来进行返回
片段(fragment)

如果多个相同的对象,并且查询的是相同的字段,那么会有很多重复的代码,使用片段,就可已实现封装(类似于Mybatis中的sql标签)

  • 语法

    {
    	GaiHero: hero(id: 11) {
    		...allFields
    	}
    	JaxHero: hero(id: 22) {
    		...allFields
    	}
    }
    
    fragment allFields on Character {
    	id
    	name
    	friends {
    		name
    	}
    }
    
    • 利用fragment可以实现封装查询的字段,并且通过扩展运算符实现展开

Schemal和类型规范

Schemal

Schemal是用来定义数据结构,例如,对象中有哪些属性,对象与对象之间的关联关系

  • 语法

    schemal {  // 定义查询,相当于命名空间
    	query: UserQuery
    }
    
    type UserQuery {  // 定义查询的类型,里面定义的查询表示前端的查询请求,用来处理查询请求
    	user(id: ID): User // 指定查询名称以及参数、查询对象类型,ID也是一种类型,`user(id: ID)`表示前端定义查询结构体的名称和参数类型,返回的对象类型是`User`
    }
    
    type User {
    	id:ID!
    	name: String
    	age: Int
    }
    
    • !后端加上符号表示该参数是非空项
类型
  • 基本类型

    • Int:32位符号整数
    • String: 字符串类型
    • Boolean:true或者false
    • ID:唯一标识符
    • Float:有符号的双精度浮点值
  • 枚举类型

    限制字段的值在一个可选的集合中,只能是定义的枚举中的值

    enum CATAGORY {
    	FRONT
    	END
    	MIDDLE
    }
    
    type Human {
    	name: string
    	kind: [CATAGORY]
    }
    

    枚举类型需要放在集合中表示

  • 接口

    接口是抽象类型,并且还可以通过implements来实现接口,实现类必须包含接口中的所有属性

    interface Human {
    	id: ID!
    	name: String
    }
    
    type editor implements IDE {
    	id: ID!
    	name: String
    	age: Int
    }
    

    除了包含接口中定义的属性之外,实现类还可以拥有自己的字段

简单介绍了GraphQL的查询规范,下一篇,将介绍Java中使用GraphQL的示例~

 类似资料: