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;}});
}
复制代码

显然这不能满足项目工程化的要求,解决这个问题有两种比较简单的方式:

  1. 把graphiql.html文件复制到项目中,用一个Controller提供GraphiQL服务,这样就可以去掉GraphiQL的相关依赖了
  2. 利用官方的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,再想想我们的需求是什么。

  1. 对项目的现有流程改动小(最大化复用现有逻辑)
  2. 支持权限控制
  3. 自动解析schema
  4. 不用硬编码、不要底层细节

这么一看的话可以得出这样的方案:

可以同时使用SpringMVC的拦截器和graphql-java-tools的优势。

似乎这种方案能满足我们的需求,但是有一个潜在的风险:

“A用户允许访问ApiA,ApiA能够访问到实体A,但是A用户没有权限访问实体A”

这时工程上就难以控制了,如果非要控制需要对实体进行权限,能做到,但是需要另外一套设计,工作量也不小。

风险

工程化实践时风险是必须要考虑的问题,GraphQL强大的自省功能(查询整个实体图的结构)能方便开发,也带来了相应的风险,同时嵌套循环查询、sql注入等问题也是需要防范的。

转载于:https://juejin.im/post/5ce55c98e51d455d877e0c9a

GraphQL(四):GraphQL工程化实践相关推荐

  1. 前端工程化实践总结 | QQ音乐商业化Web团队

    蓝字关注,回复"加群"加入前端技术群 与大家一起成长 | 导语本文主要介绍在前端工程化的一些探索和实践,结合移动端的基础库重构和UI组件库开发这两个项目详细介绍工程化方案 . 随着 ...

  2. 前端工程化实践:从开发到构建测试部署——由此及彼

    前端工程化实践 前端工程化实践 什么叫前端工程化 从实践方面来说 从理论角度来讲 前端工程化的意义: 1.规范化(从源头处约束到优雅-聚沙成塔) 1. 制定各项开发规范,让工作有章可循 2. 针对于版 ...

  3. 【推荐系统】EMBEDDING 在大厂推荐场景中的工程化实践

    " 解读YouTube.Airbnb.Alibaba的三篇经典论文,总结Embedding在工业界的一些用法和技巧,这三篇论文亮点众多,提供的经验非常值得我们去细细品味和借鉴.这篇文章篇幅较 ...

  4. python实训总结报告书_20172304 实验四python综合实践报告

    20172304 实验四python综合实践报告 姓名:段志轩 学号:20172304 指导教师:王志强 课程:Python程序设计 实验时间:2020年5月13日至2020年6月14日 实验分析 本 ...

  5. 小程序工程化实践(上篇)-- 手把手教你撸一个小程序 webpack 插件,一个例子带你熟悉 webpack 工作流程...

    本文基于 webpack 4 和 babel 7,Mac OS,VS Code 小程序开发现状: 小程序开发者工具不好用,官方对 npm 的支持有限,缺少对 webpack, babel 等前端常用工 ...

  6. Go Module 工程化实践(二):go get 取包原理篇

    接上篇: Go Module 工程化实践(一):基础概念篇. 2. go get 取包原理篇 不论是否开启Go Module功能,go get从版本控制系统VCS中取包的基础过程是类似的,除了在新的实 ...

  7. 【GraphQL】---GraphQL的基本使用

    GraphQL介绍 GraphQL是Facebook开发的一种数据查询语言,并于2015年公开发布.它是REST API的替代品. GraphQL既是一种用于API的查询语言也是一个满足你数据查询的运 ...

  8. 《Python程序设计》实验四 Python综合实践实验报告

    <Python程序设计>实验四 Python综合实践实验报告 1.实验内容 Python综合应用:爬虫.数据处理.可视化.机器学习.神经网络.游戏.网络安全等. 在华为ECS服务器(Ope ...

  9. 计算机科学与技术学习路线编程基础四大件应用实践编程(含C++学习路线)

    计算机科学与技术学习路线&编程基础四大件&应用实践编程(含C++学习路线) 基本介绍 本人211科班出身,目前大学临近毕业,想给迷茫的同行者或者后来人一些建议和推荐,少走弯路.想想自己 ...

最新文章

  1. 看一名 KDE 开发者如何使用 C++17 为项目提升巨大速度
  2. NOI Linux2.0使用系列视频集
  3. C++游戏入门书籍推荐
  4. chart控件做实时曲线显示_基于GDI+技术开发工业仪表盘控件
  5. iOS绘图框架CoreGraphics分析
  6. eBPF学习记录(四)使用libbpf开发eBPF程序
  7. 怎么修改服务器玩家等级级上限,GOM引擎等级限制了极限怎么办?传奇服务端突破等级限制的方法...
  8. RadStudio 10.3.3 Rio (Delphi C++ Builder)及TMS TAdvStringGrid控件安装方法
  9. steam的游戏服务器在哪个文件夹,使用SteamCMD在Windows上架设Don't Starve Together服务器...
  10. 004 鸿蒙应用开发-通知栏
  11. pytest常用参数
  12. poi 使用模板导出数据
  13. dijkstra标号法表格_狄克斯屈拉dijkstra标号算法.pptx
  14. PWM脉冲宽度调制,实现呼吸灯_领航者开发板
  15. 安徽省太和一中2021高考成绩查询分数,2021届安徽省太和一中高三物理高考二模试题 Word版含答案...
  16. SUN J2EE企业应用技术学习计划
  17. 浙大PTA-Python题库 编程题第一章(1-1~1-3)题解
  18. Vue全家桶之VueX(六)
  19. matplotlib的plt.ion()没用/不能交互
  20. Socialbook告诉你这才是KOL营销的终极秘诀

热门文章

  1. 图论总结 for noip
  2. ハーディー / 哈迪
  3. 2020主流室内定位技术对比
  4. 关于(archive)归档和(unarchive)解档的处理。
  5. 算法的时间复杂度表示
  6. 第二十章 指针 二 为指针分配和释放空间(转)
  7. 微信内无法分享转发网址链接,谈谈微信网址防屏蔽的办法
  8. 树支路总数 = 树节点总数 - 1
  9. Android如何处理过大图片的显示
  10. 基于lucene的案例开发:纵横小说章节列表采集