概述REST作为现代网络应用非常流行的软件架构风格,深受广大WEB开发者的喜爱。在当前的软件架构设计模式中随处可见REST的身影,但是随着REST的普及和发展,其最大的一个缺点开始暴露出来:在很多情况下,客户端所需要的数据在不同的地方往往是相似的地方,但不一样。对于同一个用户信息,在某些场景下,前端只需要用户的简要信息(姓名、头像),而在其他场景下,则需要用户的详细信息。当有很多相似但不同的地方时,需要开发更多的接口来满足前端的需求。随着这样的场景越来越多,接口越来越多,文档越来越臃肿,前后端通信的成本呈指数增长。基于以上场景,我们急需一种解决方案或框架,让前端在使用相同领域模型(DO、DTO)的数据接口时,指定需要的接口字段,后端根据需求自动适配前端的需要并返回相应的字段。这就是我们今天的主角GraphQL。场景模拟考虑如下场景:用户和文章是一对多的关系,一个用户可以发表多篇文章,同时根据文章找到相应的作者。我们需要构建如下Graphql查询:根据用户ID获取用户详情,获取该用户发表的所有文章根据文章ID获取文章详情,获取文章作者信息当然,本项目是基于在SpringBoot上。开发实践在正式开发之前,推荐大家在IDEA上安装JSGraphQL插件。这个插件方便我们写Schema,语法纠错,代码高亮等等。.创建一个SpringBoot项目通过IDEA创建一个SpringBoot项目并导入相应的jar依赖关系>org.springframework.bootspring-boot-starter-webcom.graphql-javagraphql-spring-boot-starter5.0.2com.graphql-javagraphql-java-tools5.2.4org.projectlomboklombok这里主要需要引入graphql-spring-boot-starter使用graphql-java-tools创建一个Java实体类;this.userName=userName;this.realName=realName;this.email=email;}}Post@DatapublicclassPost{privateintpostId;privateStringtitle;privateStringtext;privateStringcategory;privateUseruser;publicPost(){}publicPost(intpostId,Stringtitle,Stringtext,Stringcategory){this.postId=postId;this.title=title;this.text=text;this.category=category;}}定义了两个JAVA实体:Post和User。编写一个Schema文件,在resources/schema目录下创建一个GraphQLSchema文件。schema{query:Query,}typeQuery{#获取特定用户getUserById(id:Int):User#获取特定博客getPostById(id:Int):Post}typeUser{userId:ID!,userName:String,realName:String,email:String,posts:[Post],}typePost{postId:ID!,title:String!,text:String,category:Stringuser:User,}如上,我们通过type定义了两个对象User和Post关键词。添加!属性后表示这是一个非空属性,[Post]表示这是一个Post集合,类似于Java对象中的List。通过Query关键字定义了两个查询对象getUserById和getPostById,分别返回User对象和Post对象。schema的语法可以参考链接:https://graphql.org/learn/schema编写业务逻辑PostService@ServicepublicclassPostServiceimplementsGraphQLQueryResolver{/***为了测试,只查询id为1*/publicPostgetPostById(intid){if(id==1){Useruser=newUser(1,"javadaily","JAVA日知录","zhangsan@qq.com");Postpost=newPost(1,"Hello,Graphql","Graphql优先experience","Diary");post.setUser(user);returnpost;}else{returnull;}}}UserService@ServicepublicclassUserServiceimplementsGraphQLQueryResolver{ListuserList=Lists.newArrayList();publicUsergetUserById(intid){returnuserList.stream().filter(item->item.getUserId()==id).findAny().orElse(null);}@PostConstructpublicvoidinitUsers(){Postpost1=newPost(1,"你好,Graphql1","Graphql初体验1""Diary");Postpost2=newPost(2,"Hello,Graphql2","Graphql初体验2","Diary");Postpost3=newPost(3,"Hello,Graphql3","Graphql初体验3","日记");列表<帖子>posts=Lists.newArrayList(post1,post2,post3);Useruser1=newUser(1,"zhangsan","张三","zhangsan@qq.com");Useruser2=newUser(2,"lisi","李四","lisi@qq.com");user1.setPosts(posts);user2.setPosts(posts);userList.add(user1);userList.add(user2);}}基于Graphql的查询需要实现GraphQLQueryResolver接口,由于我们为了演示没有引入数据层,请知道配置Graphql端点server.port=8080graphql.servlet.corsEnabled=true#Configuretheendpointgraphql.servlet.mapping=/graphqlgraphql.servlet.enabled=true配置完端口和端点之后就可以测试我们写的Graphql接口了。接口地址为:localhost:8080/graphqltest这里我使用的是Chrome浏览器的AltairGraphalClient插件,当然你也可以使用其他的客户端工具,比如:graphql-playground。安装插件,在浏览器输入chrome://extensions/,在扩展中心搜索Altair,添加到浏览器。查询启动SpringBoot项目,然后在打开的Altair插件界面输入Graphql端点http://localhost:8080/graphql,然后点击Docs,将鼠标移动到需要查询的位置,点击ADDQUERY添加对应的查询.点击SendRequest可以看到查询结果:然后我们可以在Query中根据自己的需要增加或者删除接口字段,再次请求接口,会看到响应结果会自动按照我们的请求返回结果:摘要Graphql支持数据操作包括:查询:获取数据的基本查询。Mutation:支持对数据进行增删改查等操作。订阅:用于监听数据变化,通过websocket等协议将变化推送给对方。本节我们完成了基于SpringBoot的Query的数据操作,实现过程比较简单。希望这篇文章能让你对Graphql有一个整体的了解。如果你对Graphql感兴趣,后续会更新本系列文章,完成其他数据操作的整合。