Apollo GraphQL:用于返回不同类型对象的查询模式?

时间:2016-11-12 22:22:34

标签: apollostack apollo-server

我有三个不同的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等类型的对象?

提前致谢所有信息。

1 个答案:

答案 0 :(得分:4)

这里有两种选择。 声明一个接口作为返回的类型,并确保每个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,您需要在union / interace类型上提供__resolveType函数:

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

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