如何在GraphQL中获取对等字段?

时间:2016-02-29 15:16:09

标签: javascript node.js reactjs relayjs graphql

想象一下,我们有GraphQL方案,其中某些字段依赖于未在父类型中解析的对等字段。下面的代码段中有foobar

const MyType = new GraphQLObjectType({
  name 'MyType'
  fields {
    id: {
      type: GraphQLString  // Resolved from parent type
    },
    foo: {
      type: GraphQLString,
      description: 'Foo',
      resolve: function({id}, args, {rootValue:{logger, datasources:{pool}}}) {
        // Making some queries to database
      }
    },
    bar: {
      type: GraphQLString,
      description: 'Bar',
      resolve: function({id}, args, {rootValue:{logger, datasources:{pool}}}) {
        // Making some queries to database
      }
    },
    baz: {
      type: GraphQLString,
      description: 'Baz',
      resolve: function({id}, args, {rootValue:{logger, datasources:{pool}}}) {
        // This field actually depends from 'foo' and 'bar' peers.
        // How to obtain peer fields 'foo' and 'bar to resolve this field?
        // We have access to 'id' here, but this field resolved from parent type
        // and we can't access to 'foo' and 'bar' like we do it for 'id'.
      }
    }
  }
})

如何访问其他对等字段中的此字段?

1 个答案:

答案 0 :(得分:1)

每个字段必须单独解析。

const fooResolver = function(source, args, info) {
  // Making some queries to database
};
const barResolver = function(source, args, info) {
  // Making some queries to database
};
const bazResolver = function(source, args, info) {
  const foo = fooResolver(source, args, info);
  const bar = barResolver(source, args, info);
  // TODO: Resolve baz.
};

const MyType = new GraphQLObjectType({
  name 'MyType'
  fields {
    id: {
      type: GraphQLString,  // Resolved from parent type
    },
    foo: {
      type: GraphQLString,
      description: 'Foo',
      resolve: fooResolver,
    },
    bar: {
      type: GraphQLString,
      description: 'Bar',
      resolve: barResolver,
    },
    baz: {
      type: GraphQLString,
      description: 'Baz',
      resolve: bazResolver,
    },
  },
});

如果您抓取foobazbar,您会发现这会导致性能不佳。要解决此问题,请使用数据加载器。例如,使用facebook/dataloader

function cacheKeyFn(input) {
  // Produce a stable cache key string from the input
}
const fooLoader = new DataLoader(input => {
  // Return a Promise that fetches `foo` given `input`
}, {cacheKeyFn});
const barLoader = new DataLoader(input => {
  // Return a Promise that fetches `bar` given `input`
}, {cacheKeyFn});
const bazLoader = new DataLoader(input => {
  // Return a Promise that fetches `baz` given `input`
}, {cacheKeyFn});

const fooResolver = function(source, args, info) {
  return await fooLoader.load(source, args, info);
};
const barResolver = function(source, args, info) {
  return await barLoader.load(source, args, info);
};
const bazResolver = function(source, args, info) {
  return await bazLoader.load(source, args, info);
};
const bazResolver = function(source, args, info) {
  const foo = await fooResolver(source, args, info);
  const bar = await barResolver(source, args, info);
  return await bazResolver({...source, foo, bar}, args, info);
};