内容简介:严格的说,它是一种api设计思想,用来取代restful api的一种前端处于主导地位的api规范。它把前端所需要的api用类似图数据结构(graph)的方式展现出来,让前端很方便的获取所需要的数据。如果采用restful api的话,后端要持续维护api doc,但是实际场景是这样的:1.来了新需求,后端先评估和开发,后端弄得差不多,前端才开始,然后中间后端一顿猛改
严格的说,它是一种api设计思想,用来取代restful api的一种前端处于主导地位的api规范。它把前端所需要的api用类似图数据结构(graph)的方式展现出来,让前端很方便的获取所需要的数据。
起源,restful api的问题
如果采用restful api的话,后端要持续维护api doc,但是实际场景是这样的:
1.来了新需求,后端先评估和开发,后端弄得差不多,前端才开始,然后中间后端一顿猛改
2.由于多种原因,后端经常自己偷偷改掉传参或者返回值,完了接口报错,测试姐姐把前端叫过去一顿批,前端一脸懵圈,仔细检查,发现问题,找后端撕X,这样一个循环非常影响开发效率。
gql出现
由于上面这一堆的问题,facebook公司内部实践了GraphQL并开源,15年刚发布的时候引起了很多大公司和社区关注,落地了很多规范和框架。
这种叫GraphQL的东西帮助人们经过一系列定义和规范,可以发送gql请求非常方便的拿到想要的数据,甚至还可以修改数据,而不用后台的配合,而且一旦Schema确定(数据库那边定义好),前后端就可以快速并行开发,例如下图获得某个用户的信息,我想要这个用户的什么属性就写什么,graphiQl工具可以进行完整的详细的提示,请求主体简单明了
// 拿jQuery的ajax请求举例,直观一些 $.ajax({ url: '/graphql', data: { query: `query{ student{ id name age } course{ id title } }` }, success:function (res){ renderStudent (res.data.student) renderCourse (res.data.course) } }) 复制代码
gql理想使用场景
数据库建好模型,前后端可以同步开始开发需求,前端只有少数需要依赖后端接口,前端开发过程中可以方便的拿到任何想要的数据,从而节省大量联调接口的时间,迅速的完成一个项目。
实现原理
gql的实现挺复杂的,代码有点难懂,不过原理说起来比较简单易懂:grinning:
var { graphql, buildSchema } = require('graphql'); // Construct a schema, using GraphQL schema language var schema = buildSchema(` type Query { hello: String } `); // The root provides a resolver function for each API endpoint var root = { hello: () => { return 'Hello world!'; }, }; // Run the GraphQL query '{ hello }' and print out the response graphql(schema, '{ hello }', root).then((response) => { console.log(response); }); 复制代码
如上就是一个最简单的node版的gql服务器 gql把定义好的schema拿到,用root之类的resolve解析器去解析发送来的 '{ hello }'
请求,然后返回给相应的json值。上面代码打印出的response如下
{ data: { hello: 'Hello world!' } } 复制代码
当然,resolve逐层解析会有一些问题,如果resolve请求数据库,就要用到 DataLoader
DataLoader是gql服务器性能的关键一环,也是gql社区的主要推动完善方向,就像react里面的shouldComponentUpdate一样制约着gql服务器的性能。
DataLoader 能让我们从数据库读取数据并让数据能被 GraphQL 处理,我们使用 DataLoader,而不是直接通过 SQL 查询从数据库获取数据,将 DataLoader 作为代理以减少我们实际需要发送给数据库的 SQL 查询。 DataLoader 使用批处理和缓存的组合来实现。如果同一个客户端请求会造成多次请求数据库,DataLoader 会整合这些问题并从数据库批量拉取请求数据。DataLoader 会同时缓存这些数据,当有后续请求需要同样资源时可以直接从缓存获取到。
具体使用
通过服务端对请求的元数据的type进行严格的定义,我们只要在客户端发送gql请求就能返回期望的相应类型的数据
下图是请求格式,query【请求】,mutation【修改】和subscribe【订阅】是三种api发送方式,query用的多一些,mutation相对传统的restful来说不够可靠和安全,subscribe类似websocket
query { schema { types { id name // 获取根字段名 fields { id name // 获取字段名 } } } } 复制代码
正式环境下书写的大概长下图这样,一些标量、片段之类的细节不多说了,看GraphQL中文官方网站说的很详细了
辅助工具graphiql和playground
前端进行gql开发的神器,十分好用,带智能提示,这个schema里面都有哪些type,每个类型都会返回什么类型的值,数字还是字符串,一目了然,比看api文档快得多
graphiql是网页版,足够好用
playground对graphiql更进一步,多实现了一些小功能,是electron构建的应用,类似RN里面的react-devtools
封装gql的客户端&服务端框架
使用gql过程中可以自己基于业务进行二次封装,也可以使用现成框架,用于更方便的发gql请求,并与react或者vue组件进行互动。社区框架太多了,就挑几个说一下,具体可以看 github上搜集的graphql资料 全
apollo-boost
包含下图5个框架,与react-apollo一起搭配使用,是apollo社区推荐的前端使用方式,开发起来快,但是拓展修改不太方便,不适合自定义的公司项目
apollo-client
上图5个框架中最核心的一个,将各类接口微服务和数据库操作进行封装,集成redux,更易使用,但是略显臃肿,个人觉得,gql与数据库直接通信才是优势,对接rest等有点绕远路了。
relay
facebook官方前端缓存框架,与apollo-client类似,star数比apollo-client要高2k,具体使用起来差不多
apollo-server
apollo-server是一个在nodejs上构建grqphql服务端的web中间件,支持express、koa等,了解不多,毕竟gql服务器端支持很多后端语言,java等主流语言都可以封装gql服务端
graphpack
号称零配置gql服务器,适合迅速学习搭建gql服务器
原理:高度封装了apollo-server,利用webpack和nodemon本地开启一个gql服务器
Gatsby
GatsbyJS这个框架国外挺火的,是一个优秀的静态网站生成框架,优点是搭建起来,维护相当方便,甚至可以交给完全不懂编程的人。
特点是极其适合科学类介绍网站以及各种框架类文档(最适合建立markdown博客),高度封装了gql和markdown解析插件。
和restful比较的优缺点
优点
- 优点就是后端可以少招几个写接口的:dog:,可能会节约成本
- 前后端一起开发,节约工期
- 较少维护api文档,节省精力
说了这些,其实单对于前端来说,帮助不算特别大:dog:
缺点和难推广的地方
-
需要前端多少学一点类sql语句,不过大部分场景可以封装好固定的sql语句
-
封装gql不好会产生sql性能问题,三级嵌套联查还有n+1的老问题又会冒出来,需要持续优化
-
前端排除bug需要一定的后端知识,前后端架构多少了解一些
总结
1.如果尝试开发graphql项目,建议直接上apollo全家桶
2.随着社区越来越成熟,前端入门门槛也在降低,graphql可以一试
3.当前技术来说,graphql只适合对接数据库的查询,其他开发成本还是过高
篇幅所限,只是走马观花的介绍,每个小点展开都是一篇文章,就不多赘述了,如果大家想体验一下gql,带来的生产力提升绝对是物超所值的!大家有看不明白的地方或者作者说错的地方,欢迎在评论区留言,我会着手修改:kissing_heart:,另外,因为个人认知研究不断深入和前端技术快速更迭,这篇文章也会持续的进行更新维护
以上所述就是小编给大家介绍的《GraphQL简易指南》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- GitHub 简易入门指南
- 2019 简易Web开发指南
- Docker 工作原理及容器化简易指南
- 这份Koa的简易Router手敲指南请收下
- 什么的容器?Docker 工作原理及容器化简易指南
- 60题PyTorch简易入门指南,做技术的弄潮儿!
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。