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

Posted

技术标签:

【中文标题】如何在 GraphQL 中获取对等字段?【英文标题】:How to obtain peer fields in GraphQL? 【发布时间】:2016-06-12 16:44:57 【问题描述】:

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

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】:

每个字段都必须是可单独解析的。

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);
;

【讨论】:

以上是关于如何在 GraphQL 中获取对等字段?的主要内容,如果未能解决你的问题,请参考以下文章

GraphQL SPQR - 如何获取客户端使用查询请求的字段列表

如何从 GraphQL 查询中获取字段值?

在构建 Java GraphQL API 时,如何避免从数据库中过度获取(即仅获取查询中指定的字段)?

当我使用 Graphene 在 Django GraphQL API 中获取对象时,如何限制 ForeignKey 字段的项目数?

如何避免在 Relay.createcontainer 内置的 graphql 查询中添加额外的字段?

仅在graphql需要的情况下如何获取特定字段?