开局两张图,内容全靠编~html
<div style="height:335px"> <img src="https://img2018.cnblogs.com/blog/725429/201902/725429-20190213093835928-168465205.jpg" width="334px" style="float: left;margin-right:6px"/><img src="https://img2018.cnblogs.com/blog/725429/201902/725429-20190213093840589-2097035525.jpg" width="334px" style="float: left"/> </div> ok,如图所示,我在去年曾经写过一篇文章[《闲侃先后端分离的必要性》](https://www.cnblogs.com/rjzheng/p/9185502.html)。嗯,我知道确定不少人没看过。因此我作一个总结,其实啰里八嗦了一篇文章,就是想说一下如今的大型互联网项目通常是以下两种架构之一 - 先后端半分离架构 - 先后端分离架构前端
区别分离和半分离的标志在于Controller
层由不禁前端控制,Controller
在前端手里,前端手里握着组装数据的逻辑,那就是先后端分离!不然就是半分离!java
那么,半分离和分离的架构是长下面这样的 spring
ps
:中小型公司慎重,不要玩先后端分离架构!前端工做量贼大!后端
那么用上了先后端分离架构后,后端的API通常会按照Restful风格来设计!ResultFul推荐每一个URL能操做具体的资源,并且能准确描述服务器对资源的处理动做,一般服务器对资源支持get/post/put/delete/等,用来实现资源的增删改查。先后端分离的架构下,这些api-url是对接的桥梁,采用ResultFul接口地址含义才更清晰、见名知意。 那么,在实践RestFul风格的API的有一个致命的缺陷,是神马类?嗯,带着你的疑惑开始本文api
假设,此时咱们有两个资源分别是Book
和Author
,这两个资源对应的ER图以下 数组
相应的API有springboot
POST /books
GET /books/{id} POST /authors GET /authors/{id}服务器
咱们有一个需求,须要查询id=1的图书信息! 那咱们的请求地址是这样的数据结构
GET /books/1
返回结果是这样的
[{ "id": 1, "bookname": Harry Potter, "price": 56.00, "author_id": 2 }]
这时候前端MM拿到这个结果后,傻了眼!这里怎么能直接返回author_id
呢,难道直接把author_id
显示在界面上么?不可能啊,界面上要显示的是author_name
才行!
OK,那么在这种状况下,有两种方式能够解决问题! (1) 跟后端沟通,让他增长一个接口 嗯,咱们复习一下什么是VO对象。 VO(View Object):视图对象,用于展现层,它的做用是把某个指定页面(或组件)的全部数据封装起来。 那可让后端封装一个接口,后端帮你把数据拼装好,提供API以下
GET /bookVOs/1
这样直接返回的结果就是
[{ "id": 1, "bookname": Harry Potter, "price": 56.00, "author_name": J. K. Rowling }]
固然,由于你这是临时让后端加接口,可能会有以下情形产生
OK,回到正题,这样作的缺点主要有两个
(2) 本身作适配 这个也很简单,前端得到结果后,取出author_id: 2
这条记录,而后再去调用地址
GET /authors/2
获得结果,而后进行组装显示!
固然,这个时候会有以下情形产生(这就是我注孤生的缘由!)
固然,这种作法的缺点也很明显
ok,经过上面的描述,你们应该能体会到Rest的缺点:REST接口时返回的数据格式、数据类型都是后端预先定义好的,若是返回的数据格式并非调用者所指望的,调用者在处理上比较麻烦!
那么,有没有办法让前端自定灵活的使用查询语句,本身想捞什么数据就捞什么数据呢? 有的,那就是Graphql!
Graphql其实要这样理解 Graphql=grap(图)+query+lanage
是一种基于图的查询语言!那么,这张图长什么样? OK,首先你要声明一下,你的图结构,嗯,用的就是Graphql的语法啦,像下面这样
type Book { id: Int bookname: String authors: [Author] } type Author { id: Int name: String age: String } type Query { getBook(id: Int): Book } schema { query: Query }
对上面的语句进行一下解释。这里一共声明了三个类Book
、Author
、Query
!其实,Book
和Author
你们均可以猜都出来是指啥,须要注意的一点是authors: [Author]
这个地方,用了一个[]
的语法,这表明Author
是一个数组! 惟一须要说明的是,Query
是什么鬼? Query
在这儿代表了该类型是这张图的入口,也就是根节点!咱们的查询必须从根节点里的属性开始!这里我为了便于说明,只列了一个属性,也就是getBook
,该属性是入口,必须从入口开始查!
那么,生成的图是长下面这样的
这里还有一个Resolver
的概念,就是说,GragphQL
解析到getBook
方法的时候,方法体内容是啥?是在Resovler
中定义的,我这里就不贴配置了,感兴趣的能够本身去官网阅读!
OK,接下来就是第二个问题,怎么查? 根据上面我说的,只能从根开始,根是getBook
,那语句怎么写呢?以下所示 那你想加个字段,显示做者名字呢?直接像下面这么写
采用这种语法结构,后端的数据模型就变成了一张图,前端能够定制化本身的输出结构,同时能够减小先后端的沟通成本,提升灵活性!
(1)java语言中,对Graphql的支持如何? 在java中,有个jar包为graphql-java-tools
提供了对Java的支持。 另外,考虑到如今大可能是springboot项目,有大神封装好了starter包,供大家的springboot项目使用! 只需在项目中引入
<!-- graphql --> <dependency> <groupId>com.graphql-java</groupId> <artifactId>graphql-spring-boot-starter</artifactId> <version>4.0.0</version> </dependency> <dependency> <groupId>com.graphql-java</groupId> <artifactId>graphql-java-tools</artifactId> <version>4.3.0</version> </dependency>
便可让你的springboot项目拥有graphql的功能,很是方便!
(2)这样作不会加剧先后端工做量么? 说句实在话,摸着良心说,前期确实加剧了先后端的工做量! 对前端而言:须要去了解Graphql
的语法! 对后端而言:不只须要了解Graphql
的语法,还须要去编写Schema
和Resovler
! 因此短时间内,确实增长了工做量!可是从长远来看,同时下降了先后端的工做量!第一,前端不用了解后端的数据结构,GraphQL本身生成可交互式的接口文档,前端能够本身测试调用 第二,后端不用在编写什么接口文档,GrapQL自动帮你生成,用起来很是舒心!
本文介绍了Rest的缺点,以及Graphql的基本知识,但愿你们有所收获!