GraphQL 漸進學習 05-graphql-resolvers-union-聯合的使用
目標
代碼
步驟
1. 準備測試靜態數據
const notices = [{id: 1, content: '這是 notice', noticeTime: 1524710641}]
const reminds = [{id: 1, content: '這是 remind', endTime: 1524710641}]
2. 編寫 typeDefs
const typeDefs = `
scalar Date
interface Message {
content: String
}
type Notice implements Message {
content: String
noticeTime: Date
}
type Remind implements Message {
content: String
endTime: Date
}
"""
聯合類型 通知 & 提醒
"""
union MessageResult = Notice | Remind
type Query {
searchUnion (text: String!): MessageResult!
}
`
-
MessageResult
聯合對象
-
searchUnion
供客戶端查詢使用方法
3. 編寫 resolvers
const resolvers = {
Query: {
searchUnion: (_, {text}) => {
if (text === 'notice') {
return notices[0]
} else {
return reminds[0]
}
}
},
MessageResult: {
__resolveType(obj, context, info){
console.log(obj, context, info)
if(obj.noticeTime){
return 'Notice'
}
if(obj.endTime){
return 'Remind'
}
return null
}
},
Date: new GraphQLScalarType({
name: 'Date',
description: 'Date custom scalar type',
parseValue(value) {
return new Date(value) // value from the client
},
serialize(value) {
// return new Date(value).getTime()
return new Date(value) // value sent to the client
},
parseLiteral(ast) {
if (ast.kind === Kind.INT) {
return parseInt(ast.value, 10) // ast value is always in string format
}
return null
}
})
}
-
searchUnion
搜索方法實現,直接返回一條通知或提醒
-
__resolveType
返回類型定義
-
if(obj.noticeTime){
若是含有 noticeTime 字段斷定是通知
4. 合併 Schema
const schema = makeExecutableSchema({
typeDefs,
resolvers
})
測試
1. 請求 searchUnion
方法
# 請求 query
query do($text: String!) {
searchUnion(text: $text) {
... on Notice {
content
noticeTime
}
... on Remind {
content
endTime
}
}
}
# 變量 variables
{
"text": "notice"
}
# 輸出
{
"data": {
"searchInterface": {
"content": "這是 notice",
"endTime": "1970-01-18T15:31:50.641Z"
}
}
}
- 咱們能夠試着把
content
字段提出,發現查詢報錯,這個和 interface
仍是有區別的
# 錯誤
{
"errors": [
{
"message": "Cannot query field \"content\" on type \"MessageResult\". Did you mean to use an inline fragment on \"Message\", \"Notice\", or \"Remind\"?",
"locations": [
{
"line": 3,
"column": 5
}
]
}
]
}
詳細請移步
04-graphql-resolvers-interfaces-接口的使用
2. 打印 __resolveType(obj, context, info)
參數
# obj
{ id: 1, content: '這是 notice', noticeTime: 1524710641 }
# context
{}
# info
{ fieldName: 'searchUnion',
fieldNodes:
[ { kind: 'Field',
alias: undefined,
name: [Object],
arguments: [Array],
directives: [],
selectionSet: [Object],
loc: [Object] } ],
returnType: MessageResult!,
parentType: Query,
path: { prev: undefined, key: 'searchUnion' },
schema:
GraphQLSchema {
__allowedLegacyNames: undefined,
_queryType: Query,
_mutationType: Mutation,
_subscriptionType: null,
_directives: [ [Object], [Object], [Object] ],
astNode: undefined,
_typeMap:
{ Query: Query,
Post: Post,
Int: Int,
String: String,
Author: Author,
Country: Country,
Message: Message,
MessageResult: MessageResult,
Notice: Notice,
Date: Date,
Remind: Remind,
Mutation: Mutation,
AuthorInput: AuthorInput,
__Schema: __Schema,
__Type: __Type,
__TypeKind: __TypeKind,
Boolean: Boolean,
__Field: __Field,
__InputValue: __InputValue,
__EnumValue: __EnumValue,
__Directive: __Directive,
__DirectiveLocation: __DirectiveLocation },
_implementations: { Message: [Array] },
__validationErrors: [],
_possibleTypeMap: { MessageResult: [Object] } },
fragments: {},
rootValue: undefined,
operation:
{ kind: 'OperationDefinition',
operation: 'query',
name: { kind: 'Name', value: 'do', loc: [Object] },
variableDefinitions: [ [Object] ],
directives: [],
selectionSet: { kind: 'SelectionSet', selections: [Array], loc: [Object] },
loc: { start: 0, end: 173 } },
variableValues: { text: 'notice' } }
參考