我正在尝试找出如何访问args
的{{1}}字段。但是,我什至不确定UnionType的retrieveRowsWithoutLocations
函数的value
参数中包含什么。
我正在查看文档https://graphql.org/graphql-js/type/#graphqluniontype,但是它很简短,并且没有详细说明从何处获取该信息。我尝试查看其他来源,但它们不是graphql-js。
我要执行的操作是访问resolveType
并检查其值,然后允许联合决定应返回哪种类型。
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)
},
}
})
是另一个ObjectType
答案 0 :(得分:1)
您不能直接访问resolveType
(或isTypeOf
)内的任何解析程序参数。解析字段后,解析器将返回某个值,或者将解析为该值的Promise。对于返回输出类型,接口或联合的字段,此值应为JavaScript对象。正是这个值传递到resolveType
,该值用于确定运行时响应中实际返回的类型。
给出类似的模式
union Animal = Bird | Fish
type Bird {
numberOfWings: Int
}
type Fish {
numberOfFins: Int
}
type Query {
animal: Animal
}
您可以想象animal
字段的解析器返回JavaScript对象,例如{ 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}`)
}
如果我们返回特定类的实例而不是返回简单对象,则可以做得更好:
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
与解析器逻辑分离。