Apollo中的模式拼接GraphQL不能解析其他部分的类型

时间:2018-05-03 08:15:49

标签: graphql apollo apollo-server

我试图通过schema stitching使我的GraphQL架构可以合成,但我正在努力解决如何从不同的部分解析类型的属性。

以下是分解前的架构:

type Referee {
  id: ID!
  stringProp: String!
}

type Referer {
  id: ID!
  pointer: Referee!
}

type Query {
  referers: [Referer]
}

两种类型的解析器都在各自的架构中将对象{ id }扩展为{ id, stringProp }{ id, pointer: { id } },以便查询

query FromSingleSchema {
  referers: {
    id
    pointer {
      id
      stringProp
    }
  }
}

按预期结算; Query.referers解析为[{id}]个对象的列表,然后每个对象首先解析为Referer,然后通过类型解析器提取指向Referee的对象。

现在,我尝试分解架构:

// schema A
type Referee {
  id: ID!
  stringProp: String!
}

// schema B
type Referer {
  id: ID!
}

type Query {
  referers: [Referer]
}

// schema Extensions
extend type Referer {
  pointer: Referee!
}

再次撰写:

// both schemaA and schemaB have been created with makeExecutableSchema
import schemaA from './A'
import schemaB from './B'
// schemaExtensions is just a raw GraphQL string
// resolverExtensions is shown below
import { schemaExtensions, resolverExtensions } from './B'

const schema = mergeSchemas({
  schemas: [schemaA, schemaB, schemaExtensions],
  resolvers: Object.assign({}, resolverExtensions)
})

// resolverExtensions defined as follows:
{
  Referer: {
    pointer: {
      fragment: 'fragment IdFragment on Referee { id }',
      resolve: o => ({ id: o.pointerId })
    }
  }
}

有了这个,我可以毫无问题地运行这个查询:

query OnlyIdFromDecomposedSchemas {
  referers: {
    id
    pointer {
      id
    }
  }
}

但是失败了

query FullRefereeFromDecomposedSchemas {
  referers: {
    id
    pointer {
      id
      stringProp
    }
  }
}

带有错误消息

  

对于不可为空的字段Referee.stringProp,不能返回null。

我需要做什么才能让Referee类型解析器能够在{ id }可用后填写其余属性,就像在单个未分解的情况下一样模式?

1 个答案:

答案 0 :(得分:1)

我认为您正在寻找schema delegation。模式委派是一种将查询(或查询的一部分)从父模式自动转发到另一个能够执行查询的模式(称为子模式)的方法。

您可以在解析器中使用delegateToSchema这样的方法:

{
    Referer: {
      pointer : {
        resolve(parent, args, context, info) {
          return info.mergeInfo.delegateToSchema({
            schema: schemaA,
            operation: 'query',
            fieldName: 'referee', // modify according to your query for referee
            context,
            info,
          });
        }
      }
    }
  }