【问题标题】:Can I use data loader without batching我可以在没有批处理的情况下使用数据加载器吗
【发布时间】:2020-12-01 08:49:30
【问题描述】:

我对 data-loader 真正感兴趣的是每个请求的缓存。例如说我的 graphql 查询需要调用 getUser("id1") 3x。我想要一些东西来重复那个电话。

但是,对于数据加载器,我似乎需要将一组键传递到我的批处理函数中,并且多个请求将被批处理到一个 api 调用中。

这让我做了一些我不喜欢的假设:

1.) 我调用的每个服务都有一个批处理 api(我处理的一些服务没有)。

2.) 如果多个调用被批处理为 1 个 api 调用,并且该调用失败,因为其中 1 个项目未找到。通常我可以通过为该字段返回 null 来处理这个问题,这可能是一个有效的情况。但是,现在我的整个调用可能会失败,如果批处理 API 由于未找到 1 项而决定抛出错误。

无论如何都可以将数据加载器与单键请求一起使用。

【问题讨论】:

    标签: graphql graphql-js dataloader


    【解决方案1】:

    这两个假设都是错误的,因为批处理功能的实现最终取决于您。如documentation 所示,编写批处理函数时的唯一要求如下:

    批量加载函数接受一个键数组,并返回一个解析为值数组或错误实例的 Promise。

    因此,底层数据源不需要也接受 ID 数组。并且不需要一个或多个失败的调用来导致整个函数抛出,因为您可以为返回的数组中的任何特定 ID 返回 null 或错误实例。事实上,您的批处理函数应该从不抛出,而应该总是返回一个包含一个或多个错误的数组。

    换句话说,批处理函数的实现可能类似于:

    async function batchFn (ids) {
      const result = await Promise.all(ids.map(async (id) => {
        try {
          const foo = await getFooById(id)
          return foo
        } catch (e) {
          // either return null or the error
        }
      }))
    }
    

    值得注意的是,还可以将maxBatchSize 设置为1 以有效禁用批处理。但是,这不会改变批处理函数实现方式的要求——它总是需要一个 ID 数组,并且总是需要返回一个与 ID 数组长度相同的值/错误数组。

    【讨论】:

    • 有道理。但是,如果我仍然按 id 进行 http 调用,那么批处理真的有任何意义吗?
    • 不,没有。但是 DataLoader 被设计为专门用于批处理的工具,并且您尝试在没有这样的情况下使用它...这就是您所剩下的:) 如果您只需要按请求缓存,那么滚动您的自己的。你只需创建一个函数,它接受一个 id 并返回一个带有结果的 Promise,然后 memoize it,注意在每个请求上重新创建记忆函数(即在你的上下文函数中)。
    • 明白了。我现在最大的问题不是批处理,而是字段解析器重新请求根查询中已经可用的数据。你正在写它可能更容易滚动我自己的记忆。或者将公共数据存储在某个中间模型中。
    • 如果数据已经在父对象中,您也可以在解析器中有条件地检查它:(parent) => return parent.someField || fetchFromDataSource()。无论如何,祝你好运。如果答案回答了您的问题,请随时将答案标记为已接受。
    【解决方案2】:

    Daniel 的解决方案非常好,实际上是我到目前为止使用的解决方案,在将其提取到辅助函数中之后。 但我刚刚找到了另一个不需要那么多样板代码的解决方案。

    new DataLoader<string, string>(async ([key]) => [await getEntityById(key)], {batch: false});
    

    当我们设置batch: false 时,我们应该总是得到一个大小为 1 的键数组作为参数传递。因此,我们可以简单地对其进行解构并返回一个包含数据的单一大小的数组。注意返回值周围的括号!如果你省略了这些,这可能会出现可怕的错误,例如用于字符串值。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-22
      • 1970-01-01
      • 1970-01-01
      • 2012-04-08
      • 1970-01-01
      • 2017-12-31
      相关资源
      最近更新 更多