【问题标题】:Schema Stitching in Apollo GraphQL doesn't resolve types from other partsApollo GraphQL 中的模式拼接不解析来自其他部分的类型
【发布时间】:2018-05-03 18:41:42
【问题描述】:

我正在尝试通过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
    }
  }
}

带有错误信息

不能为非空字段Refeeee.stringProp返回null。

Referee 的类型解析器需要做什么才能在 { id } 可用时填充其余属性,就像在单个未分解的架构中一样?

【问题讨论】:

    标签: graphql apollo apollo-server


    【解决方案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,
              });
            }
          }
        }
      }
    

    【讨论】:

    • 我读到过,但这似乎需要我委托给另一个架构上的 query 操作 - 我目前没有,我想避免创建一个只是因为这个需要。我可以在没有显式查询操作的情况下委托给其他架构吗?
    • 我相信这里的问题实际上是您当前的 resolverExtension 如何实现 resolve 箭头功能。 Schema 委托实际上在这里是必要的——我想知道您现有的解析器是如何知道如何返回请求的字段 pointer 及其子字段的。在您的箭头函数中,您将Referer(父级,传递给您的箭头函数)与Referee 混淆了。在那里使用另一个参数名称,而不是o,它应该是referer。然后你要么使用delegateToSchema,要么你有一个简单的后端,你可以打电话询问pointer/Referee
    猜你喜欢
    • 2018-04-23
    • 2020-09-07
    • 2019-06-22
    • 2020-05-12
    • 1970-01-01
    • 1970-01-01
    • 2021-08-22
    • 2019-04-17
    • 2020-10-15
    相关资源
    最近更新 更多