在Apollo GraphQL中如何访问Dataloader内部的数据源?

时间:2020-06-26 07:44:17

标签: graphql apollo apollo-server dataloader

我是GraphQL的新手,我开始使用Apollo GraphQL。为了进行基本测试,我将GraphQL包装在《星球大战》 API(SWAPI.dev)周围。我正在使用Apollo RESTDataSource来调用Star Wars API。 在“人员”资源中,有一个“行星”数组,我想使用Dataloader批量加载。

在数据加载器内部,我需要能够批处理数据,并且需要使用我的数据源通过批处理实际获取数据。但是我找不到在数据加载器中访问数据源的方法。

我的数据加载器如下,

const DataLoader = require('dataloader');

const batchHomeworlds = async (urls) => {

    // How to access dataSources?
    //homeworlds = await dataSources.starWarsAPI.getResourcesBatch(urls)

    // Hardcoded just for testing
    homeworlds = [{url: 'http://swapi.dev/api/planets/1/', name: 'Test'}]

    const homeworldUrlMap = {};

    homeworlds.forEach(homeworld => {
        homeworldUrlMap[homeworld.url] = homeworld;
    });

    return urls.map(url => homeworldUrlMap[url])
};

module.exports = () => new DataLoader(batchHomeworlds);

Apollo服务器初始化

const server = new ApolloServer({ 
  schema,
  dataSources: () => ({
    starWarsAPI: new StarWarsAPI()
  }),
  context: () => ({
    homeworldLoader:  homeworldLoader()
  })
});

使用Dataloader的解析器如下

homeworld_planet: (parent, args, { dataSources, homeworldLoader }, info) => {
      return homeworldLoader.load(parent.homeworld)
    }

任何帮助将不胜感激!谢谢!

1 个答案:

答案 0 :(得分:0)

在数据加载器函数中访问共享对象的常用方法是将它们放入批处理函数的闭包中:

module.exports = function createDataloaders(dataSources) {
  const batchHomeworlds = async (urls) => {
    const homeworlds = await dataSources.starWarsAPI.getResourcesBatch(urls);
    return urls.map(url => homeworlds.find(h => h.url === url));
  };

  return {
    homeworldLoader: new Dataloader(batchHomeworlds),
  }
};

现在,在创建数据加载器时,您必须提供数据源。也许一开始就不必附加到数据源模式。