如何使用GraphQL buildSchema的联合

jér*_*dol 4 graphql graphql-js

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

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

这是模块的所有非常基本的用法.它运行良好,非常方便,直到我想定义一个联合:

union MediaContents = Photo|Youtube

type Media {
  Id: String
  Type: String
  Contents: MediaContents
}
Run Code Online (Sandbox Code Playgroud)

我发现无法使这项工作,查询内容做它必须做的事情,返回正确的对象,但失败的消息Generated Schema cannot use Interface or Union types for execution.

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

stu*_*ilo 8

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

您可以通过__resolveType在union上提供方法来使用联合,就像使用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;
    },
  },
};
Run Code Online (Sandbox Code Playgroud)

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

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

另请注意,解析器的签名将与常规的GraphQL.js样式匹配,因此它将(root, args, context)取代(args, context)您使用时获得的内容rootValue.