评论

收藏

[JavaScript] GraphQL的探索之路 – SpringBoot集成GraphQL之Mutation篇四 - 第317篇

开发技术 开发技术 发布于:2021-07-14 10:22 | 阅读数:615 | 评论:0

DSC0000.png




悟纤:师傅,前两天还有些东西没有梳理完,今天再来梳理下。
DSC0001.png

师傅:嗯,不错,现在有点样子了,再接再厉,离成功不远了。
DSC0002.png

悟纤:苦心人天不负,卧薪尝胆,三千越甲可吞吴。
DSC0003.png

师傅:学习就该有这种气魄,保持这种状态。
DSC0004.png

一、Mutation操作
1.1 说明
我们在一开始接收GraphQL的时候,就说过了GraphQL有两种操作:Query(查询)和Mutaion(增删改),那么对于Mutation要怎么玩呢,我们来看下。
1.2 编写AuthorMutation
对于写操作继承GraphQLMutationResolver,如下示例代码:

  •  
package com.kfit.test.resolver;import org.springframework.stereotype.Component;import com.coxautodev.graphql.tools.GraphQLMutationResolver;import com.kfit.test.bean.Author;@Componentpublic class AuthorMutation implements GraphQLMutationResolver{  public Author saveAuthor(Author author) {  //调用service方法进行保存Author,这里模拟一下设置一个id,不进行操作了。  author.setId(3);  return author;  }  }
1.3 编写.graphqls文件
我们在author.graphqls文件添加如下信息:

  •  
#这里的接收的参数的对象input AuthorInput{  #作者的id  id: Int  #作者名称  name: String  #作者照片  photo: String}#增删改方法extend type Mutation{  #保存作者信息  saveAuthor(author:AuthorInput!):Author}
这里的saveAuthor是否的参数是否可以使用Author,也就是写成如下的代码:

  •  
saveAuthor(author:Author!):Author
很遗憾,启动就会报错了:

  •  
Expected type 'Author' to be a GraphQLInputType, but it wasn't!  Was a type only permitted for object types incorrectly used as an input type, or vice-versa?
意思期望接收的参数是Author应该是一个GraphQLInputType的类型,但是实际上不是。也就是我们在配置文件定义的input AuthorInput对应的是GraphQLInputType类型。
另外很重要的一个配置就是在root.graphqls文件中进行配置type Mutation,不配置是可以正常启动的,但是extend type Mutation是没有生效的:

  •  
#定义增删改的方法type Mutation {}
1.4 启动测试
重新启动测试下吧,编写GraphQL语句:

  •  
mutation{  saveAuthor(author:{name:"小纤"}){  id,  name,  photo  }}
DSC0005.png

1.5 普通参数
对于普通参数的话,那么就无需定义input类型了:

  •  
extend type Mutation{  #保存作者信息2  saveAuthor2(name:String!,photo:String):Author}
二、GraphQL的properties
我们是在Spring Boot中集成了GraphQL,那么肯定是有一些properties可以配置了,我们看下都有哪些呐?

  •  
graphql:  servlet:  mapping: /graphql #请求映射地址  enabled: true #开启graphql  corsEnabled: true #是否允许跨域  tools:  schemaLocationPattern: "**/*.graphqls" #配置文件路径
三、GraphQL直接访问Service的方法要如何配置呢?
3.1 说明
对于GraphQL是一种描述关系,我们可以进行任何定义,我们现在想访问到Service的方法,能够定义呐,答案是肯定的,接下里我们看下如何操作呢?
3.2 定义获取Sevice的方法
我们定义AuthorAndBookQuery,这里就是获取到Book和Author的Service方法:

  •  
@Componentpublic class AuthorAndBookQuery implements GraphQLQueryResolver{  @Autowired  private BookService bookService;    @Autowired  private AuthorService authorService;    public BookService getBookService() {  return bookService;  }  public AuthorService getAuthorService() {  return authorService;  }}
3.3 定义配置文件
新建一个配置文件:authorAndBookQuery.graphqls,内容如下:

  •  
type BookService{  findById(id: Int!):Book}type AuthorService{  findById(id: Int!):Author}extend type Query{  getBookService:BookService  getAuthorService:AuthorService}
由于Book和Author已经在对应的文件对应了,这里不需要重复定义。
3.4 GraphQL语句
那么对于GraphQL又是如何编写呐?

  •  
query{  getBookService{  findById(id:1){    id,    name  }  }}
四、你可能不知道的小知识点
4.1 查询Query可以省略
我们发起查询请求的时候,是可以省略关键词Query的,如下:

  •  
{  findBookById(id: 1) {  id,  name  }}
DSC0006.png

4.2 指定返回的字段可以使用空格分隔或者换行
GraphQL指定要返回的字段,一方面可以使用逗号分隔,另外一方面可以使用空格或者换行符号(此时不需要逗号),如下:

  •  
{  findBookById(id: 1) {  id name  }}
4.3 同一个文件的extend type可以多个
对于extend type在同一个文件是可以多个的:

  •  
#查询方法extend type Query{  #通过作者id进行查询作者的信息  findAuthorById(id: Int!):Author}#可以多个,也可以和上面的那个一起extend type Query{  findAuthorById2(id: Int!):Author}
不同文件也是可以的多个的,这个我们在Book和Author的时候,就是这么使用了。
4.4 不同的Query方法相同了会怎么样呐?
我们在BookQuery和AuthorQuery都有一个方法:

  •  
public String findById(int id) {  return "";  }
在配置文件配置:

  •  
extend type Query{  findById(id:Int!):String}
启动就会报错:

  •  
FieldResolverError: Found more than one matching resolver for field 'FieldDefinition{name='findById', type=TypeName{name='String'}
大概意思就是找到了两个方法findById。
对于GraphQLQueryResolver的实现类都是root Query下的关系,所以AuthorQuery和BookQuery有相同的方法的话,那么GraphQL就不知道要调用哪个了。
4.5 在.graphQL文件定义了为实现的方法
如果在.graphQL文件定义了未实现的方法,或者方法名称写错了,也是报异常的:

  •  
FieldResolverError: No method found with any of the following signatures (with or without one of [interface graphql.schema.DataFetchingEnvironment] as the last argument)
悟纤小结
悟纤:通过这几节的内容,已经是把GraphQL基本的讲的很清楚了,我已经尽力了,如果还不懂的话,请自行敲三遍代码(^_^),这里简单进行总结下:
(1)GraphQL解决了接口对查询字段差异性的要求:①指定查询字段返回;②多接口合并查询。
(2)GraphQL的Query和Mutation操作。
(3)使用curl发起请求GraphQL。
通过具体的使用,我们会发现使用GraphQL有这么一些好处:
(1)前端自己可以定义要返回的数据及结构,降低前后端沟通成本;
(2)无需编写接口文档(GraphQL会根据schema自动生成API文档);
(3)schema拼接,可以组合和连接多个GraphQL API,合并为一个,减少请求次数;
DSC0007.gif
我就是我,是颜色不一样的烟火。
我就是我,是与众不同的小苹果。
à悟空学院:https://t.cn/Rg3fKJD
SpringBoot视频:http://t.cn/A6ZagYTi
Spring Cloud视频:http://t.cn/A6ZagxSR
SpringBoot Shiro视频:http://t.cn/A6Zag7IV
SpringBoot交流平台:https://t.cn/R3QDhU0
SpringData和JPA视频:http://t.cn/A6Zad1OH
SpringSecurity5.0视频:http://t.cn/A6ZadMBe
Sharding-JDBC分库分表实战:
http://t.cn/A6ZarrqS
分布式事务解决方案「手写代码」:
http://t.cn/A6ZaBnIr
深入理解JVM内存模型/调优实战:
http://t.cn/A6wWMVqG


关注下面的标签,发现更多相似文章