GraphQL 是什么
GraphQL 是 Facebook 开源的一套数据交互方案, 它并非某种具体的语言或者框架, 它只是提供了一套解决方案, 这套解决方案通过 GraphQL 规范 https://facebook.github.io/graphql/draft/ 进行定义, 不同语言可以有自己的 GraphQL 实现, 目前已经有很多语言完成了 GraphQL 的实现, 可以在这里 https://github.com/chentsulin/awesome-graphql 查看.
怎么使用 GraphQL
GraphQL 致力于提供一种直观的弹性语法系统, 用以描述客户端程序设计时的数据需求以及数据交互行为. 通俗地讲就是允许客户端在请求中精确的定义自己需要什么, 服务端根据客户端的请求精确的返回相应的内容. 比如有如下两个相互关联的实体:
- Teacher{
- name: String
- phone: String
- age: Int
- }
- School{
- id: String
- name: String
- address: String
- teachers: List<Teacher>
- }
使用 GraphQL 查询指定学校的名称是这样的:
- school(schoolId: "schoolId1"){
- name
- }
返回:
- data{
- "name" : "北京大学"
- }
如果想要查询学校的名称以及所有老师的名字和电话:
- school(schoolId: "schoolId1"){
- name
- teachers{
- name
- phone
- }
- }
将得到:
- data{
- "name" : "北京大学"
- "teachers" : [
- {
- "name" : "李老师",
- "phone" : "13312345678"
- },
- {
- "name" : "张老师",
- "phone" : "13312345673"
- },
- {
- "name" : "王老师",
- "phone" : "13312345672"
- }
- ]
- }
以上只演示了 GraphQL 提供的查询 (query) 功能, GraphQL 还支持修改 (mutation) 和订阅(subscription).
要使得客户端可以使用 GraphQL 的方式请求数据, 首先需要在服务端提供 GraphQL 服务, 这里 https://github.com/chentsulin/awesome-graphql 可以查看现有的实现了 GraphQL 的平台, 关于如何搭建 GraphQL 的服务, 请查看 GraphQL(二):GraphQL 服务搭建 https://www.jianshu.com/p/331a3e1aeba2
同时, GraphQL 提供了强大的开发者工具 GraphiQL https://github.com/graphql/graphiql , 可以实时查看数据模型和 API, 为前后端开发者提供了一个便捷的沟通平台.
为什么要使用 GraphQL
通过上面的内容, 大致可以了解 GraphQL 给前后端数据交互带来的变化.
使用 RESTful 风格的 API, 会从指定接口加载数据. 每个接口都明确定义了返回的数据结构. 这意味着客户端需要的数据, 已经在 URL 中制定好了. GraphQL 中采用的方式截然不同, GraphQL 的 API 通常只暴露一个接口, 而不是返回固定数据结构的多个接口. GraphQL 返回的数据结构不是一成不变的, 而是灵活的, 让客户端来决定真正需要的是什么数据.
这样的变化能够在一定程度上解决使用 RESTful 风格接口完成数据交互时会遇到的问题:
多端点, 每个 API 都有自己的路径需要管理
API 数量庞大, 新人自学习困难
GraphQL 通过图的方式来组织模型, 结合 GraphiQL https://github.com/graphql/graphiql , 新人能够快速上手
后端数据模型难以规范
RESTful 接口多为页面驱动, 后端可能会设计很多差别不大的模型, 目前并没有一种强约束去要求后端开发人员规范模型, GraphQL 要求在一开始就完成业务模型的分析和定义, 避免后面业务模型的泛滥
在 API 设计时往往是面向页面的, 而页面相比模型具有更差的稳定性
API 文档维护工作量大
RESTful 的 API 需要管理大量文档, 但是依然存在文档更新, 文档查阅方便的问题, 虽然可以动用人力完善工具去解决, 但是 GraphQL 天然就自带文档工具特性. 我们在定义字段时, 一并写上 description, 通过 GraphiQL 可以实时查看:
- type School {
- id: ID!
- # 学校 id
- schoolId: String
- # 学校名称
- schoolName: String
- # 学校年龄
- schoolAge: Int
- # 学校地址
- schoolAddress: String
- # 学校包含的老师
- teachers: [Teacher]
- # 校长
- master: String
- }
GraphiQL 中查看:
数据聚合较为麻烦
这是在后端经常需要处理的问题, 比如, 客户端需要一些数据, 我们定义了一个 RESTful 的接口, 但是这些数据分别在 A 和 B 服务中, 最终我们会在后台手动聚合 A 和 B 的数据到一个模型里返回. 而 GraphQL 通过不同的 Resolver 天然完成了数据聚合功能
GraphQL 解除了接口和数据之间的绑定, 对业务数据模型做了抽象和整理, 以图的方式来明确模型之间的关系, 通过这些关系, 具体业务场景可以定制自己的数据, 不同的业务场景只要基于同样一套基础数据模型就可以复用过往的接口.
以上好处讲起来有些抽象, 需要多多实践多多体会.
来源: http://www.bubuko.com/infodetail-2977303.html