专栏首页黄腾霄的博客2020-5-16-理解Graphql

2020-5-16-理解Graphql

之前2020-5-6-restful理解 - huangtengxiao和大家提及了RESTfulAPI的一个弊端,就是接口膨胀。

也提到了一个解决方案——GraphQL

今天就和大家讲一下什么是GraphQL


RESTfulAPI的问题

请求爆炸

我们先假设有这样一个商城应用,后端对应着用户,订单,物流三个微服务,通过RESTfulAPI暴露服务。

在客户端,我们需要完成查询指定用户的所有商品的物流信息。

那么我们的请求行为应该是这样的。

如上图所示,我们需要先通过用户ID获取从用户服务中获取订单信息,从其中抽取订单ID。

然后再通过订单ID从订单服务中查询订单详情,从中抽取物流ID。

然后再根据物流ID从物流服务中获取物流详细。

我们可以看到,这样的交互模式下,一个小小的功能要发出三个请求,经历6次糟糕的网络传输。

这样会大大增加请求响应时间,造成用户体验下降。

接口爆炸

还是这个例子,现在我们客户端部分有App和小程序,他们都期望查询订单信息。

但是不同的是,多端模型不一致问题。

对于小程序,可能只需要订单的基本信息,用户简单查询。

而对于App,可能需要的是更加详细的订单数据,以进行更加复杂的操作。

对于这种情况,我们有这么几种方案:

  • 要么我们获取所有数据,然后在客户端筛选。 但是这样会导致小程序端获取过多不必要数据。
  • 要么我们通过HATEOAS,传入客户端对应的版本类型,进行区分返回数据 但是HATEOAS实现比较复杂,而且将前端业务逻辑往下沉,之后改动起来容易头大
  • 要么我们给两个不同的API,不同的端调用自己的API 简单有效,但是工作量大

什么是GraphQL

GraphQL是一种针对于API的查询语言,能够让你像查询SQL那样调用后端API。

它为上述RESTful的两大问题提供了解决方案:

  • 通过请求发送指定的Schema,得到对应的数据
  • 一次请求获得多个资源。

在GraphQL的wiki上的例子是这样的

//post
{
    orders {
        id
        productsList {
            product {
                name
                price
            }
            quantity
        }
        totalAmount
    }
}
//response
{
    "data": {
        "orders": [
            {
                "id": ,
                "productsList": [
                    {
                        "product": {
                            "name": "orange",
                            "price": 1.5
                        },
                        "quantity": 
                    }
                ],
                "totalAmount": 
            }
        ]
    }
}

这里的请求的含义是获取所有的订单信息,订单中要包含对应的id,总价,商品列表,商品列表中要包含商品的信息。

我们可以看到使用GraphQL,发出的请求和收到的响应格式是一一对应的。

而且注意,这里的订单服务和商品目录服务可以是不同的服务,分别获得数据后在GraphQL服务端进行组装、

至于所见即所得,在GraphQL上可以看到这样的一个例子。

这样对于不同的客户端需求,只要写不同的schema即可。

这样业务逻辑也在前端,而且数据量也不会变大。

GraphQL理解

改造商城例子

上述的商城例子用GraphQL改造起来后,看起来是这样的。

我们的所有数据能在一个请求中完成。

注意上图中各个微服务之间的调用我们使用的是虚线

因为实际上我们不可能让各个微服务之间进行互相调用,来完成这样的查询

实际的情况如下图所示

GraphQL这边相当于一个API网关,作为用户端和后端实际服务之间的 中间层,

承担了请求schema的解析,对于不同服务的调用,返回数据的拼接。

但是它的好处是这些顺序请求,都是在服务端完成的,减少了网络通信造成的延迟。

而且利用schema解析,可以满足客户端各种类型的数据需求。

GraphQL接入

如果你理解了GraphQL网关的地位,就能够发现GraphQL可以在现在有RESTfulAPI基础上进行无缝接入。

而且,对于RESTfulAPI和其他的GraphQL服务混合情况下,也是可以顺利使用的。

GraphQL弊端

GraphQL也存在一些弊端:

  • 对于小型项目,GraphQL比较重,多了一层中间层。 所以简单应用没有必要使用GraphQL
  • GraphQL的子查询本质上还是链式查询,所以在服务端还是可能因为较多的嵌套导致响应变慢 因此,对于一些性能敏感应用,或者是可以异步请求的数据,不建议使用GraphQL
  • GraphQL的查询对单点故障敏感,部分查询失败会导致整个结果失败。 所以如果你的某一个服务容易出现单点故障,那就建议将抽离在GraphQL之外,单独提供服务

参考文档:


本文会经常更新,请阅读原文: https://xinyuehtx.github.io/post/%E7%90%86%E8%A7%A3Graphql.html ,以避免陈旧错误知识的误导,同时有更好的阅读体验。

本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。欢迎转载、使用、重新发布,但务必保留文章署名黄腾霄(包含链接: https://xinyuehtx.github.io ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请 与我联系

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 2019-1-28-wcf入门(7)

    在2019-1-27-wcf入门(6) - huangtengxiao中介绍会话时,我们已经接触过实例化。

    黄腾霄
  • 2019-11-12-C++CLI的枚举在C#中看不见

    实际上在C++/CLI中我们可以定义两种枚举类型,不加class关键字的是标准C++枚举,加class关键字的是托管枚举或者叫做CLR枚举。

    黄腾霄
  • 2018-8-24-快捷调试Nuget包

    我们有一个超级基础的库A,我们的多个公共组件B,C,D,和最终产品E都依赖于库A。

    黄腾霄
  • 安息吧 REST API,GraphQL 长存

    即使与 REST API 打交道这么多年,当我第一次了解到 GraphQL 和它试图解决的问题时,我还是禁不住把本文的标题发在了 Twitter 上。

    疯狂的技术宅
  • Coursera 的 GraphQL 之旅

    Coursera 的客户端开发人员钟情于 GraphQL 的灵活性,类型安全性和良好的社区支持,我们对 GraphQL 的喜爱众~所~周~知。然而,我们并没有过...

    疯狂的技术宅
  • RITA:一款功能强大的真实情报威胁分析工具

    RITA是一款专门针对网络流量分析与测试人员的开源框架,广大研究人员可以利用RITA来对收集到的安全威胁情报进行深度分析。

    FB客服
  • 往ABAP gateway system上和Cloud Foundry上部署HTML5应用

    版权声明:本文为博主汪子熙原创文章,未经博主允许不得转载。 https://jerry.bl...

    Jerry Wang
  • Java工程师的职业规划

    初级程序员:做一些静态的界面; 程序员:做一些增删改查的小模块; 中级程序员:做逻辑较复杂的模块; 高级程序员:做核心模块; 项目经理:系统的整体架构; 部门经...

    Java团长
  • 阿里首席架构师分享的Java工程师职业规划

    如果刚毕业,就多花几年积累经验,不可能靠一门绝技吃遍天下,不要指望java 赚钱多还是c++ or .NET 赚钱多。太早。 积累经验为主。积累设计,架构,测试...

    lyb-geek
  • Python通过多帧静态图像制作GIF动态图像

    下面的代码可以把多个png图像文件合并为一个GIF动态图像文件,如果无法正常执行的话,除了需要使用pip安装pillow和images2fig扩展库之外,很可能...

    Python小屋屋主

扫码关注云+社区

领取腾讯云代金券