GraphQL介绍
什么是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" } } }GaiHero、jaxHero表示为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或者falseID:唯一标识符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 }除了包含接口中定义的属性之外,实现类还可以拥有自己的字段