第一次了解到 GraphQL 是查阅 Github 文档时,偶然看到 v4 版本文档只要一个链接就可以完成所有获取数据和更新数据请求,当时看到觉得特别惊艳,能跳出 REST 请求模式,构建出全新的一套环境来实现网络请求,GraphQL 的开发者确实很有想法。
我们在 Facebook 的代码开源网站上找到了 官方回答, 大意是说:
在开发带 WebView 的 APP 时需要兼容 Android、iOS 环境不一致从而设计不同 API 接口,于是 API 接口越来越多,逻辑也越来越繁杂,于是就开发了 GraphQL 来解决这个问题。
仔细一想,在现有的网络请求模式下,我们在日常开发中使用REST
模式开发接口时也会遇到这类情况。
随着我们做的产品功能越来越复杂,需要依赖后台模块API数量越来越多,逐渐不好维护。
每个请求的 Path 和它的功能是绑定的,意味着这个 Path 的 API 只能用于特定场景下,可复用性不强。
GET 或 POST 请求的 Path 通常是描述该 API 功能的,链接就暴露了 API 功能对于黑产做中间人攻击非常有利。
使用 API 的前端开发人员无法限制接口返回内容,而且在接口复用中,通常会接收到很多不需要的字段,导致请求包很大,网络耗时变长。
API 命名时缺少一个统一规范,和开发人员个人喜好也有关系。而且随着版本迭代,为了兼容现有业务,当前现有的 API 请求模块甚至还会出现很多 v1/v2的命名,导致接口命名不够统一简洁。
通常,复杂的功能不是一个 API 可以搞定的。这时我们会并发请求多次,但浏览器也有最大请求数量限制。当我们使用 HTTP/1.1 以上时,还可以多路复用,避免多个 TCP 慢启动,但多个请求毕竟每个都带有 HTTP 头,而且分包上也会有损耗。如果可以通过一个请求实现所有数据获取,那就最好不过了。
GraphQL 便很好地解决了当前 REST 请求模式的缺点,它是如何解决的呢?我们带着这个疑问了解一下它。
GraphQL,从字面上意思图查询
。它强调的是对象与对象之间建立的图联系,把这种联系提供给外部使用。
相比于现有的接口请求更强调的功能实现,GraphQL可以提供更底层的对象以及他们引用或包含关系,从而让前端实现功能时有更大的发挥空间。
语法相关内容可以参考官方文档
。
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 开发工具清晰地看到对象属性及其类型,以及我们当前的输入哪里有误。
因为 GraphQL 只返回显示请求的数据,我们在给对象新增属性或能力时,对于现有的接口请求返回是一致的,无需像 REST 请求一样需要用 v1/v2 来兼容原有数据,方便向前兼容。
GraphQL 有这么多优点,是否我们项目里面都应该使用它呢?
说到底,使用 GraphQL 构建项目是一个前期苦了后端爽了前端的方案。对于根深蒂固的大项目,要促使整个系统改造实属不易。但如果你觉得你们的后期收益大于改变的成本,那就大胆去推动吧。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。