GraphQL(四):GraphQL工程化实践
Demo到产品化还有很长的路要走,尤其是要在尽量小的影响当前框架的前提下引入新的方法。
GraphiQL
GraphiQL是整个GraphQL优势的重要一环,然而默认的GraphiQL不允许配置graphql服务的地址(就是点击GraphiQL上的运行按钮去请求数据的地址),要弄明白这一点很容易,找到graphiql-spring-boot-autoconfigure包,里面有graphiql.html文件,请求数据的endpoint是硬编码的:
function graphQLFetcher(graphQLParams) {// This example expects a GraphQL server at the path /graphql.// Change this to point wherever you host your GraphQL server.return fetch('/graphql', {method: 'post',headers: {'Accept': 'application/json','Content-Type': 'application/json',},body: JSON.stringify(graphQLParams),credentials: 'include',}).then(function (response) {return response.text();}).then(function (responseBody) {try {return JSON.parse(responseBody);} catch (error) {return responseBody;}});
}
复制代码
显然这不能满足项目工程化的要求,解决这个问题有两种比较简单的方式:
- 把graphiql.html文件复制到项目中,用一个Controller提供GraphiQL服务,这样就可以去掉GraphiQL的相关依赖了
- 利用官方的GraphiQL的React组件自己搭建GraphiQL页面,这样定制化更方便
GraphQL Voyager
强大的实体关系图生成工具
GitHub已经提供了GraphQL的接口,实体关系图可以在GraphQL Voyager里查看,Custom Schema允许提供自己的实体关系数据生成实体关系图,简直不能更好用。
身份认证和权限控制
在GraphQL(三):GraphQL集成SpringBoot原理中提到GraphQL本身不带身份认证和权限控制(这也确实不是它该做的事儿),但是它对查询提供了回调方法(Instrumentation接口),在GraphQL.java文件中可以看到这部分逻辑:
public ExecutionResult execute(String requestString, String operationName, Object context, Map<String, Object> arguments) {//执行回调InstrumentationContext<ExecutionResult> executionCtx = instrumentation.beginExecution(new ExecutionParameters(requestString, operationName, context, arguments));assertNotNull(arguments, "arguments can't be null");log.debug("Executing request. operation name: {}. Request: {} ", operationName, requestString);//解析回调InstrumentationContext<Document> parseCtx = instrumentation.beginParse(new ExecutionParameters(requestString, operationName, context, arguments));Parser parser = new Parser();Document document;try {document = parser.parseDocument(requestString);parseCtx.onEnd(document);} catch (ParseCancellationException e) {RecognitionException recognitionException = (RecognitionException) e.getCause();SourceLocation sourceLocation = new SourceLocation(recognitionException.getOffendingToken().getLine(), recognitionException.getOffendingToken().getCharPositionInLine());InvalidSyntaxError invalidSyntaxError = new InvalidSyntaxError(sourceLocation);return new ExecutionResultImpl(Collections.singletonList(invalidSyntaxError));}//验证回调InstrumentationContext<List<ValidationError>> validationCtx = instrumentation.beginValidation(new ValidationParameters(requestString,operationName,context,arguments,document));Validator validator = new Validator();List<ValidationError> validationErrors = validator.validateDocument(graphQLSchema, document);validationCtx.onEnd(validationErrors);if (validationErrors.size() > 0) {return new ExecutionResultImpl(validationErrors);}ExecutionId executionId = idProvider.provide(requestString, operationName, context);Execution execution = new Execution(queryStrategy, mutationStrategy, subscriptionStrategy, instrumentation);ExecutionResult result = execution.execute(executionId, graphQLSchema, context, document, operationName, arguments);executionCtx.onEnd(result);return result;}
复制代码
通过对每次执行GraphQL查询进行拦截可以实现类似SpringMVC拦截器的效果,但是需要自己实现SpringMVC中 @RequiredRole 注解的功能。
在GraphQL(二):GraphQL服务搭建中提到有两种搭建GraphQL服务的方式,当时并没有考虑身份认证和权限控制的问题,假如要在那两种方法的基础上加入身份认证和权限控制,有哪些成本呢?
- graphql-java + graphql-java-spring 此方案使用了SpringMVC的DispatcherServlet,所以完全可以复用原有的拦截器机制,权限认证需要基于Instrumentation自己实现,工作量大
- graphql-spring-boot-starter + graphql-java-tools 此方案用了自己的GraphQLServlet,没有包含拦截器机制,要加上身份认证可以自己重写GraphQLServlet加入拦截器机制,或者在Instrumentation接口上做文章,两种方案都需要较大改动,且后期维护难度大,权限控制也需要基于Instrumentation自己实现
综合来看:
ok,再想想我们的需求是什么。
- 对项目的现有流程改动小(最大化复用现有逻辑)
- 支持权限控制
- 自动解析schema
- 不用硬编码、不要底层细节
这么一看的话可以得出这样的方案:
可以同时使用SpringMVC的拦截器和graphql-java-tools的优势。
似乎这种方案能满足我们的需求,但是有一个潜在的风险:
“A用户允许访问ApiA,ApiA能够访问到实体A,但是A用户没有权限访问实体A”
这时工程上就难以控制了,如果非要控制需要对实体进行权限,能做到,但是需要另外一套设计,工作量也不小。
风险
工程化实践时风险是必须要考虑的问题,GraphQL强大的自省功能(查询整个实体图的结构)能方便开发,也带来了相应的风险,同时嵌套循环查询、sql注入等问题也是需要防范的。
转载于:https://juejin.im/post/5ce55c98e51d455d877e0c9a
GraphQL(四):GraphQL工程化实践相关推荐
- 前端工程化实践总结 | QQ音乐商业化Web团队
蓝字关注,回复"加群"加入前端技术群 与大家一起成长 | 导语本文主要介绍在前端工程化的一些探索和实践,结合移动端的基础库重构和UI组件库开发这两个项目详细介绍工程化方案 . 随着 ...
- 前端工程化实践:从开发到构建测试部署——由此及彼
前端工程化实践 前端工程化实践 什么叫前端工程化 从实践方面来说 从理论角度来讲 前端工程化的意义: 1.规范化(从源头处约束到优雅-聚沙成塔) 1. 制定各项开发规范,让工作有章可循 2. 针对于版 ...
- 【推荐系统】EMBEDDING 在大厂推荐场景中的工程化实践
" 解读YouTube.Airbnb.Alibaba的三篇经典论文,总结Embedding在工业界的一些用法和技巧,这三篇论文亮点众多,提供的经验非常值得我们去细细品味和借鉴.这篇文章篇幅较 ...
- python实训总结报告书_20172304 实验四python综合实践报告
20172304 实验四python综合实践报告 姓名:段志轩 学号:20172304 指导教师:王志强 课程:Python程序设计 实验时间:2020年5月13日至2020年6月14日 实验分析 本 ...
- 小程序工程化实践(上篇)-- 手把手教你撸一个小程序 webpack 插件,一个例子带你熟悉 webpack 工作流程...
本文基于 webpack 4 和 babel 7,Mac OS,VS Code 小程序开发现状: 小程序开发者工具不好用,官方对 npm 的支持有限,缺少对 webpack, babel 等前端常用工 ...
- Go Module 工程化实践(二):go get 取包原理篇
接上篇: Go Module 工程化实践(一):基础概念篇. 2. go get 取包原理篇 不论是否开启Go Module功能,go get从版本控制系统VCS中取包的基础过程是类似的,除了在新的实 ...
- 【GraphQL】---GraphQL的基本使用
GraphQL介绍 GraphQL是Facebook开发的一种数据查询语言,并于2015年公开发布.它是REST API的替代品. GraphQL既是一种用于API的查询语言也是一个满足你数据查询的运 ...
- 《Python程序设计》实验四 Python综合实践实验报告
<Python程序设计>实验四 Python综合实践实验报告 1.实验内容 Python综合应用:爬虫.数据处理.可视化.机器学习.神经网络.游戏.网络安全等. 在华为ECS服务器(Ope ...
- 计算机科学与技术学习路线编程基础四大件应用实践编程(含C++学习路线)
计算机科学与技术学习路线&编程基础四大件&应用实践编程(含C++学习路线) 基本介绍 本人211科班出身,目前大学临近毕业,想给迷茫的同行者或者后来人一些建议和推荐,少走弯路.想想自己 ...
最新文章
- 看一名 KDE 开发者如何使用 C++17 为项目提升巨大速度
- NOI Linux2.0使用系列视频集
- C++游戏入门书籍推荐
- chart控件做实时曲线显示_基于GDI+技术开发工业仪表盘控件
- iOS绘图框架CoreGraphics分析
- eBPF学习记录(四)使用libbpf开发eBPF程序
- 怎么修改服务器玩家等级级上限,GOM引擎等级限制了极限怎么办?传奇服务端突破等级限制的方法...
- RadStudio 10.3.3 Rio (Delphi C++ Builder)及TMS TAdvStringGrid控件安装方法
- steam的游戏服务器在哪个文件夹,使用SteamCMD在Windows上架设Don't Starve Together服务器...
- 004 鸿蒙应用开发-通知栏
- pytest常用参数
- poi 使用模板导出数据
- dijkstra标号法表格_狄克斯屈拉dijkstra标号算法.pptx
- PWM脉冲宽度调制,实现呼吸灯_领航者开发板
- 安徽省太和一中2021高考成绩查询分数,2021届安徽省太和一中高三物理高考二模试题 Word版含答案...
- SUN J2EE企业应用技术学习计划
- 浙大PTA-Python题库 编程题第一章(1-1~1-3)题解
- Vue全家桶之VueX(六)
- matplotlib的plt.ion()没用/不能交互
- Socialbook告诉你这才是KOL营销的终极秘诀