【问题标题】:Dataloader is not working as expected in graphql resolverDataloader 在 graphql 解析器中没有按预期工作
【发布时间】:2019-10-05 12:39:05
【问题描述】:

我有一个数据加载器和我的 graphql,如下所示:

async function testDataLoader(accountNumber, req, args) {
  const dummy = new DataLoader(async accountNumber => {
    return new Promise(async (resolve, reject) => {
      // rest call
      return resolve([<rest result>])
    });
  });

  return  dummy.load(accountNumber)
}

export default {
  Friends: {
    query1: async ({req, args}) => {
      const data = await testDataLoader(["12121"], req, args);
      // do something with data
    }

    query2: async ({req, args}) => {
      const data = await testDataLoader(["12121"], req, args);
      // do something with data
    }
  }
};

当我们查询时:

Friends {
  query1
  query2
}

我希望 dataloader 只调用一次我的休息服务。但是,我可以看到我的休息被调用了两次。不确定,我在哪里犯了错误。

【问题讨论】:

    标签: graphql apollo apollo-server


    【解决方案1】:

    问题是每次调用testDataLoader 时,都会创建一个新的DataLoader 实例。您应该为每个请求(每个正在加载的资源)创建一个 DataLoader 实例。这样,每次您调用 load 时,您都在与同一个缓存进行交互。

    可以执行以下操作:

    const dummy = new DataLoader(...);
    async function testDataLoader(accountNumber) {
      return  dummy.load(accountNumber)
    }
    

    但这会在请求之间保留 DataLoader,这是您不想做的。您应该做的是创建 DataLoader 实例作为上下文的一部分,每次执行请求时都会重新创建该实例。

    const context = async ({ req }) => {
     return {
       testLoader = new DataLoader(...),
     };
    },
    const server = new ApolloServer({
      ...
      context,
    })
    

    然后直接在你的解析器中调用你的加载器:

    query2: async (parent, args, context) => {
      const data = await context.testLoader.load(["12121"]);
      ...
    }
    

    【讨论】:

    • 非常感谢。您的回答让我错过了我在 graphql 中的知识空白!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-05-16
    • 2011-03-30
    • 2014-01-26
    • 2021-11-19
    • 2023-03-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多