如何在 GraphQL buildSchema 中使用联合

How to use unions with GraphQL buildSchema

以下是我如何使用 GraphQL 架构字符串创建架构并将其附加到我的 Express 服务器:

var graphql = require('graphql');
var graphqlHTTP = require('express-graphql');
[...]
    return graphqlHTTP({
      schema: graphql.buildSchema(schemaText),
      rootValue: resolvers,
      graphiql: true,
    });

这些都是模块的基本用法。它运行良好并且非常方便,直到我想定义一个联合:

union MediaContents = Photo|Youtube

type Media {
  Id: String
  Type: String
  Contents: MediaContents
}

我没有找到使这项工作正常进行的方法,查询 Contents 做了它必须做的事情,returns 正确的对象但失败并显示消息 Generated Schema cannot use Interface or Union types for execution

在使用 buildSchema 时是否可以使用联合?

这正是我们创建 graphql-tools 软件包的原因,它就像是 buildSchema 的生产就绪、增压版本:http://dev.apollodata.com/tools/graphql-tools/resolvers.html#Unions-and-interfaces

您可以通过在联合上提供一个 __resolveType 方法来简单地使用联合,就像通常使用 GraphQL.js:

# Schema
union Vehicle = Airplane | Car

type Airplane {
  wingspan: Int
}

type Car {
  licensePlate: String
}

// Resolvers
const resolverMap = {
  Vehicle: {
    __resolveType(obj, context, info){
      if(obj.wingspan){
        return 'Airplane';
      }
      if(obj.licensePlate){
        return 'Car';
      }
      return null;
    },
  },
};

唯一的变化是,不再提供您的解析器作为根对象,而是使用 makeExecutableSchema:

const graphqlTools = require('graphql-tools');
return graphqlHTTP({
  schema: graphqlTools.makeExecutableSchema({
    typeDefs: schemaText,
    resolvers: resolvers
  }),
  graphiql: true,
});

另请注意,解析器的签名将匹配常规 GraphQL.js 样式,因此它将是 (root, args, context) 而不是 (args, context),这是您使用时得到的rootValue.

如果您要返回包含所有信息的对象,您可以在对象中添加一个 __typename 字段。像这样:

return {
  token: res.token,
  user: {
    __typename: 'YOUR_TYPE_HERE',
    ...res.user
  }
};