GraphQL可以实现获取多个资源只用一个请求,这个是能覆盖所有场景的么,我们应该怎么做取舍

问题描述

GraphQL可以实现获取多个资源只用一个请求,这个应该是覆盖不到所有场景的吧,很多情况下我们并不能做到一个页面只写一次GraphQL查询,就可以获取这个页面需要的所有数据的

问题出现的环境背景及自己尝试过哪些方法

有一种场景: 一个页面里展示的信息, info1, info2, info3,前端需要请求多个接口,info1对应的接口A中的a字段,info2对应的接口B中的b字段,info3对应的接口C中的c字段

// /api/user/A
{
    id: 1111,
    name: '张三',
    a: '当前页面要展示的info1',
    b: 'b'
    // 其他字段
}
// /api/order/B
{
    id: 2222,
    name: 'hahah',
    a: 'a'
    b: '当前页面要展示的info2',
    // 其他字段
}
// /api/system/C
{
    id: 3333,
    name: 'hehe',
    a: 'a'
    c: '当前页面要展示的info3',
    // 其他字段
}

这个时候,稍微有点脾气的前端,都会去找后端撕逼,

前端A: “就这三个字段,你还让我请求三个接口,你不能一个接口都返回给我吗”,
后端B:“哎, 我也想啊,但是xxxxx, 所以我这边不好改,”,
...
最后那就这样吧。

当然,我举得这个例子是一个很简单的场景,实际开发过程中要比这个还要复杂;

如果使用GraphQL的话,前端自己写查询,这个页面需要哪些需哪数据,后端就返回给哪些数据,
这是考虑到后端所有的接口都在同一个域下面,但是一般比较复杂的系统,后端都会分为不同的域, 用户域,商品域,基础模块域,交易域等等,这时即使用了GraphQL也可能

后端C:“你看其他都不是我负责的域,我要是自己给你封装一个,我自己底层需要经过xxxxx等复杂的步骤去获取其他域的,这个很复杂, 你还是直接去他哪个域去查询吧”,

有两种方法,

  • 你就再多写一个GraphQL
  • 自己写一个node中间层,中间层来处理这些接口数据的聚合,换句话说,中间层来聚合成一个GraphQL查询来返回给前端, 中间层分别取调用服务端的三个接口,然后把三个接口返回的数据聚合成前端所需要的

疑问就是,有没有更好的办法来实现调用一个接口查询多个资源的问题?

阅读 4.7k
5 个回答

我们也在考虑如何将GraphQL作为接口协议应用在项目中,目前还在调研阶段。我是长期工作在后端的工程师。在阅读了一些的资料后,我更倾向于将GraphQL独立出一个服务来支撑前端查询,并将查询翻译成后端可以接受的请求来获取数据(或写入数据),并依照Schema定义好的格式响应给前端。这可能就是你所说的“中间层”方案。

这也许也是GraphQL标准制定团队所推崇的方案,从他们公布的开发原则的10条来看,这种方案实现了单一图原则,又能很好的摆脱业务逻辑,更多的关注数据之间的关系。

后端在这种环境下面临的较大难题是查询复杂度对响应效率的影响问题,以及多应用间的授权问题等,前者我打算采用并发请求进行查询优化,后者其实跟业务逻辑相关,我还没开始考虑。

新手上路,请多包涵

我们也在考虑如何将GraphQL作为接口协议应用在项目中,目前还在调研阶段。我是长期工作在后端的工程师。在阅读了一些的资料后,我更倾向于将GraphQL独立出一个服务来支撑前端查询,并将查询翻译成后端可以接受的请求来获取数据(或写入数据),并依照Schema定义好的格式响应给前端。这可能就是你所说的“中间层”方案。

这也许也是GraphQL标准制定团队所推崇的方案,从他们公布的开发原则的10条来看,这种方案实现了单一图原则,又能很好的摆脱业务逻辑,更多的关注数据之间的关系。

后端在这种环境下面临的较大难题是查询复杂度对响应效率的影响问题,以及多应用间的授权问题等,前者我打算采用并发请求进行查询优化,后者其实跟业务逻辑相关,我还没开始考虑。

新手上路,请多包涵

APIJSON_Auto_get.jpg
用 APIJSON 就可以,支持任意多表、任意关联查询,
不用写Schema,Type,resolver等一堆东西,
它会自动将前端传的 JSON 参数转为 SQL 语句执行并返回结果,
期间自动校验权限、结构、内容,自动防 SQL 注入。

还有自动化的各种JOIN(INNER, LEFT, RIGHT等)解决N+1问题。
还支持多字段排序order by,多字段分组group by,聚合函数having
等几乎所有 MySQL, PostgreSQL, Oracle 的常规功能。

https://github.com/APIJSON/AP...

APIJSON 全方位对比 GraphQL
https://www.zhihu.com/questio...

一般可以选择加Node中间层,也就是现在到处传的BFF,它不影响原有后台服务。其实还是要看具体情况权衡。

完全可以实现,如果是使用graphql聚合原来的接口,那么只要接口有,都可以聚合。

能不能实现聚合所有的字段关键在于你如何写graphql。而不是graphql能不能做到,这只是一个像RESTful一样的规范,关键在于你的理解和技术。

问题都不能假设。首先建议楼主熟读2遍官方文档。再熟悉一下相关的工具库和最佳实践。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
宣传栏