https://cloud.tencent.com/developer/user/1027298 Omniqia https://cloud.tencent.com/developer/user/1027298 发表于前端之心 https://cloud.tencent.com/developer/column/1552
204
腾讯云服务器 年付 3 折起
首次购买云服务器 最低 3 折起 超高性价比
限时抢购 https://cloud.tencent.com/act/southwest?from=11037
第一次了解到 GraphQL 是查阅 GitHub 文档 https://developer.github.com/v4/ 时, 偶然看到 v4 版本文档只要一个链接就可以完成所有获取数据和更新数据请求, 当时看到觉得特别惊艳, 能跳出 REST 请求模式, 构建出全新的一套环境来实现网络请求, GraphQL 的开发者确实很有想法.
GraphQL 开发初衷
我们在 Facebook 的代码开源网站上找到了 官方回答, 大意是说:
在开发带 webView 的 App 时需要兼容 Android,iOS 环境不一致从而设计不同 API 接口, 于是 API 接口越来越多, 逻辑也越来越繁杂, 于是就开发了 GraphQL 来解决这个问题.
仔细一想, 在现有的网络请求模式下, 我们在日常开发中使用 REST 模式开发接口时也会遇到这类情况.
REST 模式痛点
API 爆炸
随着我们做的产品功能越来越复杂, 需要依赖后台模块 API 数量越来越多, 逐渐不好维护.
高耦合
每个请求的 Path 和它的功能是绑定的, 意味着这个 Path 的 API 只能用于特定场景下, 可复用性不强.
安全风险
GET 或 POST 请求的 Path 通常是描述该 API 功能的, 链接就暴露了 API 功能对于黑产做中间人攻击非常有利.
加载太多无用内容
使用 API 的前端开发人员无法限制接口返回内容, 而且在接口复用中, 通常会接收到很多不需要的字段, 导致请求包很大, 网络耗时变长.
API 命名规范
API 命名时缺少一个统一规范, 和开发人员个人喜好也有关系. 而且随着版本迭代, 为了兼容现有业务, 当前现有的 API 请求模块甚至还会出现很多 v1/v2 的命名, 导致接口命名不够统一简洁.
实现一个功能需要请求多个 API
通常, 复杂的功能不是一个 API 可以搞定的. 这时我们会并发请求多次, 但浏览器也有最大请求数量限制. 当我们使用 HTTP/1.1 以上时, 还可以多路复用, 避免多个 TCP 慢启动, 但多个请求毕竟每个都带有 HTTP 头, 而且分包上也会有损耗. 如果可以通过一个请求实现所有数据获取, 那就最好不过了.
解决痛点
GraphQL 便很好地解决了当前 REST 请求模式的缺点, 它是如何解决的呢? 我们带着这个疑问了解一下它.
GraphQL 特征
GraphQL, 从字面上意思图查询. 它强调的是对象与对象之间建立的图联系, 把这种联系提供给外部使用.
相比于现有的接口请求更强调的功能实现, GraphQL 可以提供更底层的对象以及他们引用或包含关系, 从而让前端实现功能时有更大的发挥空间.
语法相关内容可以参考官方文档 https://graphql.org/learn/ .
唯一端点 (endpoint)
GraphQL 的所有请求都是通过一个链接来实现的. 例如 GitHub v4 文档的端点是 https://api.github.com/graphql.
强调对象
GraphQL 强调的是描述一个对象, 而非功能, 而且可以按需取数据. 举个栗子:
- query {
- hero {
- name
- }
- }
我们通过以上请求体是想要获取 hero 的 name 属性, 通常这和我们后台 Model 结构一致的, 请求返回结构也是对等的.
同时获取多个数据
我们在上面的 query 里面可以同时放多个对象描述, 可以一次性把需要的数据都拉取回来, 减少网络请求数量, 极大优化了网络请求负载, 同时也方便前端开发.
类型系统与自省
GraphQL 的基本数据类型有五种: Int,Float,String,Boolean,ID. 前四种比较常见, 第五种 ID 类型对于我们编码时可以不必关注. 它是 GraphQL 标识对象时唯一的 key, 会序列化成一段字符串.
通过类型系统, 我们在开发时可以通过 GraphQL 开发工具清晰地看到对象属性及其类型, 以及我们当前的输入哪里有误.
无版本 API
因为 GraphQL 只返回显示请求的数据, 我们在给对象新增属性或能力时, 对于现有的接口请求返回是一致的, 无需像 REST 请求一样需要用 v1/v2 来兼容原有数据, 方便向前兼容.
GraphQL 有这么多优点, 是否我们项目里面都应该使用它呢?
然而, 不是所有情况都适合 GraphQL 发挥
如果你的项目功能足够很简单, 只有屈指可数个 API, 那么使用它反而会让项目结构变得复杂;
在需要 CDN 缓存时, 它只有一个端点, 无法通过 URL 来定位资源的;
对于传输二进制内容, 它也没法实现;
它一次携带多个数据请求单元, 当其中某个请求结果超时, 其它请求也会等待返回. 因此, 如果你现在项目里结果不可预期的请求比较多时, 也不建议使用它.
总结
说到底, 使用 GraphQL 构建项目是一个前期苦了后端爽了前端的方案. 对于根深蒂固的大项目, 要促使整个系统改造实属不易. 但如果你觉得你们的后期收益大于改变的成本, 那就大胆去推动吧.
原创声明, 本文系作者授权云 + 社区发表, 未经许可, 不得转载.
如有侵权, 请联系 yunjia_community@tencent.com 删除.
编辑于 5 天前
APIHTTPGitGitHub
来源: https://www.qcloud.com/developer/article/1455812