Dataloader在graphql解析器中未按预期工作

时间:2019-05-18 12:31:52

标签: graphql apollo apollo-server

我有一个dataloader和我的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仅调用一次我的休息服务。但是,我能够看到我的其余部分被称为两次。不知道我在哪里犯错。

1 个答案:

答案 0 :(得分: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"]);
  ...
}