1

我有三个不同的 PostGres 表,每个表都包含不同类型的关联。每种类型的数据库字段都不同——这就是它们位于三个单独的表中的原因。

我有一个组件可以潜在地访问任何类型的关联。现在从我到目前为止遇到的示例看来,一个组件通常与一个 GraphQL 查询相关联,例如:

const withData = graphql(GETONEASSOCIATE_QUERY, {
    options({ navID }) {
        return {
            variables: { _id: navID}
        };
    }
    ,
    props({ data: { loading, getOneAssociate } }) {
        return { loading, getOneAssociate };
    },


});

export default compose(
    withData,
    withApollo
)(AssociatesList);

似乎给定的 GraphQL 查询只能返回单一类型记录,例如在模式中:

getOneAssociate(associateType: String): [associateAccountingType]

问题:是否可以设计一个 GraphQL 模式,使得单个查询可以返回不同类型的对象?解析器可以接收一个 associateType 参数,该参数将告诉它要引用哪个 postGres 表。但是模式会是什么样子,以便它可以根据需要返回 associateAccountingType、 associateArtDirectorType、 associateAccountExecType 等类型的对象?

提前感谢所有人提供的任何信息。

4

1 回答 1

5

您在这里有两个选择。声明一个接口作为返回的类型,并确保这些 associateTypes 中的每一个都扩展了该接口。如果您在所有这些类型上都有公共字段,这是一个好主意。它看起来像这样:

interface associateType {
  id: ID
  department: Department
  employees: [Employee]
}

type associateAccountingType implements associateType {
  id: ID
  department: Department
  employees: [Employee]
  accounts: [Account]
}

type associateArtDirectorType implements associateType {
  id: ID
  department: Department
  employees: [Employee]
  projects: [Project]
}

如果您没有任何公共字段,或者出于某种原因您希望这些类型不相关,则可以使用联合类型。此声明要简单得多,但要求您为查询的每个字段使用一个片段,因为引擎假定这些类型没有公共字段。

union associateType = associateAccountingType | associateArtDirectorType | associateAccountExecType

更重要的一件事是如何实现一个解析器,它会告诉你的 graphql 服务器和你的客户端什么是实际的具体类型。对于 apollo,您需要在联合/交互类型上提供 __resolveType 函数:

{
  associateType: {
    __resolveType(associate, context, info) {
      return associate.isAccounting ? 'associateAccountingType' : 'associateArtDirectorType';
    },
  }
},

此函数可以实现您想要的任何逻辑,但它必须返回您正在使用的类型的名称。associate参数将是您从父解析器返回的实际对象。context是您常用的上下文对象,并info保存查询和架构信息。

于 2016-11-23T08:58:14.483 回答