我正在试图弄清楚如何访问args
的retrieveRowsWithoutLocations
字段。但是,我甚至不确定UnionType的value
函数中的resolveType
参数是什么。
我正在查看文档https://graphql.org/graphql-js/type/#graphqluniontype,但它非常简短,并没有详细说明从哪里获取信息。我试过看其他来源,但它们不是graphql-js。
我想要做的是访问args.type
并检查它的值,然后允许联合决定它应该返回哪种类型。
let rows_union =
new graphql.GraphQLUnionType({
name:
"rows_union",
types:
[
many_item,
many_list,
many_display_list,
],
resolveType(value)
{
switch(value)
{
case "item":
return many_item
case "list":
return many_list
case "display_list":
return many_display_list
}
}
})
// Define the Query type
var query =
new graphql.GraphQLObjectType({
name: "Query",
fields:
{
retrieveRowsWithoutLocations:
{
type:
rows_union,
args:
{
_id:
{
type:
nonNullId()
},
page:
{
type:
nonNullInt()
},
page_length:
{
type:
nonNullInt()
},
type:
{
type:
nonNullString()
},
},
async resolve ()
{
}
},
}
})
let many_type =
new graphql.GraphQLObjectType({
name: "many_"+name,
fields: {
results: {
type: graphql.GraphQLList(type)
},
total: {
type: graphql.GraphQLNonNull(graphql.GraphQLInt)
},
}
})
type
是另一个ObjectType
您无法直接访问resolveType
(或isTypeOf
)中的任何解析器参数。解析字段后,解析程序将返回一些值,或者将解析为该值的Promise。对于返回输出类型,接口或联合的字段,此值应为JavaScript对象。然后将此值传递给resolveType
,union Animal = Bird | Fish
type Bird {
numberOfWings: Int
}
type Fish {
numberOfFins: Int
}
type Query {
animal: Animal
}
用于确定运行时响应中实际返回的类型。
给出类似的架构
animal
你可以想象{ numberOfWings: 2 }
字段的解析器返回像{ numberOfFins: 4 }
resolveType: (value) => {
if (value.numberOfWings !== undefined) {
return 'Bird'
} else if (value.numberOfFins !== undefined) {
return 'Fish'
}
throw new TypeError(`Unable to resolve type for Animal with value: ${value}`)
}
这样的JavaScript对象。在这里,我们可以使用一个简单的启发式来确定类型:
resolveType: (value) => {
if (value instanceof BirdModel) {
return 'Bird'
} else if (value instanceof FishModel) {
return 'Fish'
}
throw new TypeError(`Unable to resolve type for Animal with value: ${value}`)
}
如果不返回简单对象,我们返回特定类的实例,我们可以做得更好:
results
无论我们的条件逻辑是什么样的,只要记住我们总是只测试解析器返回的值,无论发生什么。
如果您不使用类并且两个或更多类型共享相同的结构,事情会变得有点棘手。或者,就像你的情况一样,当区别属性(union Animal = Cat | Dog
type Cat {
numberOfPaws: Int
}
type Dog {
numberOfPaws: Int
}
)是一个数组时,因为检查其中一个元素是不行的。想象一下,我们的联盟看起来像这样:
// Resolver for animal field
resolve: () => {
return {
numberOfPaws: 4,
kind: 'Dog',
}
}
// Union
resolveType: (value) => {
return value.kind
}
不幸的是,我们必须依靠我们的解析器提供一些额外的信息。例如,我们可以返回一些任意字段来标识类型:
resolveType
但是,依靠isTypeOf
和resolve: () => {
return {
numberOfPaws: 4,
__typename: 'Dog',
}
}
的默认实现,我们实际上可以做得更好:
__typename
通过像这样显式返回resolveType
,我们实际上可以省略完全定义resolveType
。但是,请记住,再次,这会对解析程序产生依赖关系。在可能的情况下,您应该倾向于使用instanceof
和resolveType
检查,而不是将qazxswpoi与解析器逻辑分离。