NestJS - 数据加载器如何与 GraphQL Shield 结合使用?

问题描述 投票:0回答:1

我最近发现,因为我的一些屏蔽规则中进行了异步调用,所以导致我的数据加载器批处理函数被多次调用,而它们只应该被调用一次,这给我带来了 N+1 问题。

我相信这是由于

dataloader
库要求所有批处理函数调用都发生在同一个事件循环“tick”(source)期间,而我的屏蔽规则中进行的异步调用阻止了这种情况。

这是我在我的

app
中传递给
useFactory
GraphQLModule 函数:

  useFactory(dataloaderService: DataloaderService, usersService: UsersService) {
    return {
      context: async ({ req }: { req: Request }) => {
        const loaders = dataloaderService.getLoaders();
        const services = { usersService };
        return { loaders, services };
      },
      transformSchema: (schema: GraphQLSchema) => {
        schema = applyMiddleware(schema, shieldPermissions);
        return schema;
      },
    };
  },

有没有办法同时使用数据加载器和像 GraphQL Shield 这样的授权库?我当前的配置是否有任何问题可能导致此问题?

graphql permissions nestjs authorization apollo-server
1个回答
0
投票

传递

batchScheduleFn
的选项解决了问题:

  private _createGroupsLoader() {
    return this._getDataLoader<number, Group>(
      async (groupIds) =>
        this.groupsService.getGroupsBatch(groupIds as number[]),
      {
        batchScheduleFn: (callback) => setTimeout(callback, 5),
      }
    );
  }

在不传递

batchScheduleFn
的情况下,数据加载器在内部使用它自己的调度程序,该调度程序使用
process.nextTick
setImmediate

使用 5 ms 的原因:

我们当前的启发是将执行交回主线程 每 5 毫秒。 5ms 并不是一个神奇的数字,重要的是它 即使在 120fps 设备上也比单帧小,因此不会阻塞 动画。

来源:https://dev.to/tsirlucas/integrating-dataloader-with-concurrent-react-53h1

© www.soinside.com 2019 - 2024. All rights reserved.