2017-05-29 63 views
3

這裏是我如何使用GraphQL模式字符串創建模式並將其連接到我的Express服務器:如何使用工會與GraphQL buildSchema

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 
} 

我發現沒有辦法,使這項工作,查詢內容做的事情必須做,返回正確的對象,但失敗的消息Generated Schema cannot use Interface or Union types for execution

使用buildSchema時是否可以使用聯合?

回答

6

這正是爲什麼我們創建了graphql-tools包,就像是一個生產就緒,機械增壓版的buildSchemahttp://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)而不是僅當您使用rootValue時得到的(args, context)

+0

好的,這就是我的想法,沒有辦法用buildSchema來做到這一點。我想在確定添加一個依賴項之前確定:) 還有一個問題:我不太瞭解resolverMap的語法,是Vehicle在這裏定義的內聯類(我以前從未見過, m更多的是C++人,並且在JS中一直很困惑:D) –

+1

好的,整合完成,小菜一碟。 非常感謝! –

+1

這是一個很好的答案。正是我在找的東西。 –