- GraphQL简介
- GraphQL 对比 REST API 有什么好处?
- GraphQL 思考模式
- GraphQL执行逻辑
- GraphQL应用的基本架构
- GraphQL特点总结
- GraphQL支持的数据操作
- GraphQL的核心概念:图表模式(Schema)
- 标量类型(Scalar Type)
- 对象类型(Object Type)
- 类型修饰符(Type Modifier)
- 其他类型
- Graphql 技术接入架构
- 服务端实现
- 客户端实现
REST作为一种现代网络应用非常流行的软件架构风格,自从Roy Fielding博士在2000年他的博士论文中提出来到现在已经有了20年的历史。它的简单易用性,可扩展性,伸缩性受到广大Web开发者的喜爱。
REST 的 API 配合JSON格式的数据交换,使得前后端分离、数据交互变得非常容易,而且也已经成为了目前Web领域最受欢迎的软件架构设计模式。
但随着REST API的流行和发展,它的缺点也暴露了出来:
- 滥用REST接口 ,导致大量相似度很高(具有重复性)的API越来越冗余。
- 对于前端而言:REST API粒度较粗 ,难以一次性符合前端的数据要求,前端需要分多次请求接口数据。增加了前端人员的工作量。
- 对于后端而言:前端需要的数据往往在不同的地方具有相似性,但却又不同 ,比如针对同样的用户信息,有的地方只需要用户简要信息(比如头像、昵称),有些地方需要详细的信息,这就需要开发不同的接口来满足这些需求。当这样的相似但又不同的地方多的时候,就需要开发更多的接口来满足前端的需要。增加了后端开发人员的工作量和重复度。
那我们来分析一下,当前端需求变化,涉及到改动旧需求时 ,会有以下这些情况:
做加法 :
产品需求增加,页面需要增加功能,数据也就相应的要增加显示,那么REST接口也需要做增加,这种无可厚非。
做减法 :
产品需求减少,页面需要减少功能,或者减少某些信息显示,那么数据就要做减法。
一种通常懒惰的做法是,前端不与后端沟通,仅在前端对数据选择性显示。
因为后端接口能够满足数据需要,仅仅是在做显示的时候对数据进行了选择性显示,但接口的数据是存在冗余的,这种情况一个是存在数据泄露风险,另外就是数据量过大时造成网络流量过大,页面加载缓慢,用户流量费白白消耗,用户体验就会下降。
另外一种做法就是告知后端,要么开发新的接口,要么,修改旧接口,删掉冗余字段。
但一般来说,开发新接口往往是后端开发人员会选择的方案,因为这个方案对现有系统的影响最低,不会有额外的风险。
修改旧接口删除冗余数据的方案往往开发人员不会选择,这是为什么呢?
这就涉及到了系统的稳定性问题了,旧接口往往不止是一个地方在用,很有可能很多页面、设置不同客户端、不同服务都调用了这个接口获取数据,不做详细的调查,是不可能知道到底旧接口被调用了多少次,一旦改动旧接口,涉及范围可能非常大,往往会引起其他地方出现崩溃。改动旧接口成本太高,所以往往不会被采取。
同时做加减法:
既有加法,又有减法,其实这种就跟新需求没啥区别,前端需要重做页面,后端需要新写接口满足前端需要,但是旧接口还是不能轻举妄动(除非确定只有这一处调用才可以删除)。
往往这个时候,其实用到的数据大多都是来自于同一个DO或者DTO,不过是在REST接口组装数据时,用不同的VO来封装不同字段,或者,使用同样的VO,组装数据时做删减。
看到这些问题是不是觉得令人头大?
所以需求频繁改动是万恶之源 ,当产品小哥哥改动需求时,程序员小哥哥可能正提着铁锹赶来......
那么有没有一种方案或者框架,可以使得在用到同一个领域模型(DO或者DTO)的数据时,前端对于这个模型的数据字段需求的改动,后端可以根据前端的改动和需要,自动适配,自动组装需要的字段,返回给前端呢?如果能这样做的话,那么后端程序猿小哥可能要开心死了,前端妹子也不用那么苦口婆心地劝说后端小哥哥了。
所以GraphQL 隆重出世了!那么问题来了!
Part 1 What is GraphQL
GraphQL简介
- GraphQL是一种新的API标准,它提供了一种比REST更有效、更强大和更灵活的替代方案。
- 它是由Facebook开发并开源的,现在由来自世界各地的公司和个人组成的大型社区维护。
- GraphQL本质上是一种基于api的查询语言,现在大多数应用程序都需要从服务器中获取数据,这些数据存储可能存储在数据库中,API的职责是提供与应用程序需求相匹配的存储数据的接口。
- 它是数据库无关的,而且可以在使用API的任何环境中有效使用,我们可以理解为GraphQL是基于API之上的一层封装,目的是为了更好,更灵活的适用于业务的需求变化。
简单的来说,它
它的工作模式是这样子的:
基于 Spring Boot + MyBatis Plus + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能
GraphQL 对比 REST API 有什么好处?
REST API 的接口灵活性差、接口操作流程繁琐,GraphQL 的声明式数据获取,使得接口数据精确返回,数据查询流程简洁,照顾了客户端的灵活性。
客户端拓展功能时要不断编写新接口(依赖于服务端),GraphQL 中一个服务仅暴露一个 GraphQL 层,消除了服务器对数据格式的硬性规定,客户端按需请求数据,可进行单独维护和改进。
REST API 基于HTTP协议,不能灵活选择网络协议,而传输层无关、数据库技术无关使得 GraphQL 有更加灵活的技术栈选择,能够实现在网络协议层面优化应用。
举个经典的例子:前端向后端请求一个book对象的数据及其作者信息。我用动图来分别演示下REST和GraphQL是怎么样的一个过程。先看REST API的做法:
REST API获取数据
再来看GraphQL是怎么做的:
GraphQL获取数据
可以看出其中的区别:
与REST多个endpoint不同,每一个的 GraphQL 服务其实对外只提供了一个用于调用内部接口的端点,所有的请求都访问这个暴露出来的唯一端点。
Endpoints对比REST API's Endpoints
GraphQL 实际上将多个 HTTP 请求聚合成了一个请求,将多个 restful 请求的资源变成了一个从根资源 POST 访问其他资源的 Comment 和 Author 的图,多个请求变成了一个请求的不同字段,从原有的分散式请求变成了集中式的请求,因此GraphQL又可以被看成是图数据库的形式。
图数据库模式的数据查询
那我们已经能看到GraphQL的先进性,接下来看看它是怎么做的。
基于 Spring Cloud Alibaba + Gateway + Nacos + RocketMQ + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能
GraphQL 思考模式
使用GraphQL接口设计获取数据需要三步:
GraphQL获取数据三步骤
1、首先要设计数据模型,用来描述数据对象,它的作用可以看做是VO,用于告知GraphQL如何来描述定义的数据,为下一步查询返回做准备;
2、前端使用模式查询语言(Schema)来描述需要请求的数据对象类型和具体需要的字段(称之为声明式数据获取);
3、后端GraphQL通过前端传过来的请求,根据需要,自动组装数据字段,返回给前端。
GraphQL的这种思考模式是不是完美解决了之前遇到的问题呢?先总结它的好处:
在它的设计思想中,GraphQL 以图的形式将整个 Web 服务中的资源展示出来,客户端可以按照其需求自行调用,类似添加字段的需求其实就不再需要后端多次修改了。
创建GraphQL服务器的最终目标是:允许查询通过图和节点的形式去获取数据。
GraphQL执行逻辑
有人会问:
- 使用了GraphQL就要完全抛弃REST了吗?
- GraphQL需要直接对接数据库吗?
- 使用GraphQL需要对现有的后端服务进行大刀阔斧的修改吗?
答案是:NO!不需要!
它完全可以以一种不侵入的方式来部署,将它作为前后端的中间服务,也就是,现在开始逐渐流行的 前端 —— 中端 —— 后端 的三层结构模式来部署!
那就来看一下这样的部署模式图:
GraphQL执行逻辑
也就是说,完全可以搭建一个GraphQL服务器,专门来处理前端请求,并处理后端服务获取的数据,重新进行组装、筛选、过滤,将完美符合前端需要的数据返回。
新的开发需求可以直接就使用GraphQL服务来获取数据了,以前已经上线的功能无需改动,还是使用原有请求调用REST接口的方式,最低程度的降低更换GraphQL带来的技术成本问题!
如果没有那么多成本来支撑改造,那么就不需要改造!
只有当原有需求发生变化,需要对原功能进行修改时,就可以换成GraphQL了。