GraphQL和嵌套资源会造成不必要的调用?
我读了GraphQL规范,找不到一种方法来避免1 + N * number_of_nested调用,我错过了什么吗?GraphQL和嵌套资源会造成不必要的调用?
即查询具有嵌套订单和地址的类型客户端,如果有10个客户端,它将为每个客户端调用10个客户端+10个调用。每个客户端调用+10个调用.addresses。
有没有办法避免这种情况?并不是说缓存UUID的东西是相同的,这些都是不同的值,如果你将GraphQL指向一个可以进行连接的数据库,那将是非常糟糕的,因为你可以对任意数量的客户端进行3次查询。
我问这个,是因为我想将GraphQL与一个可以高效地获取嵌套资源的API集成,并且如果在解决这个问题之前有办法解决整个图表会很好,试图将一些嵌套的东西放入只需一个电话。
或者我弄错了,GraphQL只能用于微服务?
这是GraphQL的“解析器体系结构”的一个难点。您必须通过在每个解析器中执行大量I/O操作来避免产生大量网络延迟。首先,使用SQL DBMS的应用程序通常会遇到N + 1问题。你需要使用一些批处理和/或缓存技术来解决这个问题。
如果您在服务器上使用Node.js的,我有两个工具推荐:
DataLoader - 为配料解析器为每个字段和缓存个人记录的数据库无关的工具。
Join Monster - SQL定制的工具,可读取每个查询和您的模式,并为您编译SQL查询。它利用JOIN和DataLoader风格的批处理在少数(或单个)SQL查询中从表中获取数据。
我认为,你所谈论的是将GraphQL与SQL数据库后端结合使用。标准本身是数据库不可知的,它不关心,你将如何解决代码中可能的N + 1 SELECT问题。话虽这么说,GraphQL服务器的特定服务器端实现引进缓解这一问题的许多不同的方式:
- 据我所知,Ruby实现能够利用活动记录和宝石,如bullet应用水平配料已执行的数据库调用。
- JavaScript的实现可能会利用DataLoader库,它们具有类似的将批量执行的许诺序列集合在一起的技术。你可以在行动here看到它。
- Elixir和Python实现具有关于已执行子查询的运行时信息的概念,可用于确定哪些数据将进一步用于执行GraphQL查询,并可能预取它。
- F#实现类似于Elixir,但是插件本身可以执行执行树的实时分析以更好地描述哪些字段可能在代码中使用,从而允许从数据库模型中更轻松地拆分GraphQL域模型。
- 许多实现(即PostGraph)将底层数据库模型直接绑定到GraphQL模式。在这种情况下,GQL查询通常会直接转换为数据库查询语言。
这不仅适用于SQL后端,如果您有一个可以在一个请求中获取数据的API,那么执行多个操作会有点不好。 正如我看到javascript和python实现都有一个缓存,它只能解决已经看到的对象,比如用户 - >朋友,朋友也是用户实例,如果你做了很多嵌套,它肯定会解决问题。 –
谢谢,安迪!也许我不会使用节点,也许是python或rust,但是知道它可能来自GraphQL的体系结构,我将从那里开始并尝试构建一个解决方案。 –