graphqlj-js 联合类型,访问参数
graphqlj-js union type, access args
我正在尝试弄清楚如何访问 retrieveRowsWithoutLocations
的 args
字段。但是,我什至不确定 UnionType 的 resolveType
函数中的 value
参数是什么。
我正在查看文档 https://graphql.org/graphql-js/type/#graphqluniontype,但它非常简短,没有详细说明从何处获取该信息。我试过查看其他来源,但它们不是 graphql-js。
我想做的是访问 args.type
并检查它的值,然后允许联合决定它应该 return.
的类型
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
)内的任何解析器参数。当一个字段被解析时,解析器 returns 一些值,或者一个将解析为该值的 Promise。对于 return 输出类型、接口或联合的字段,该值应该是 JavaScript 对象。然后将此值传递给 resolveType
,用于确定在运行时响应中实际 return 编辑的类型。
给定一个类似
的架构
union Animal = Bird | Fish
type Bird {
numberOfWings: Int
}
type Fish {
numberOfFins: Int
}
type Query {
animal: Animal
}
您可以想象 animal
字段 returns 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}`)
}
如果我们 return 特定 类 实例而不是 return 简单对象,我们可以做得更好:
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}`)
}
无论我们的条件逻辑是什么样子,请记住,我们始终只是在测试由解析器 return 编辑的值,无论它是什么。
如果您不使用 类 并且两个或多个类型共享相同的结构,事情就会变得有点棘手。或者,就像您的情况一样,当区分 属性 (results
) 是一个数组时,因为检查其中一个元素是不行的。想象一下我们的工会看起来像这样:
union Animal = Cat | Dog
type Cat {
numberOfPaws: Int
}
type Dog {
numberOfPaws: Int
}
不幸的是,在这里,我们必须依靠我们的解析器来提供一些额外的信息。例如,我们可以 return 一些任意字段来标识类型:
// Resolver for animal field
resolve: () => {
return {
numberOfPaws: 4,
kind: 'Dog',
}
}
// Union
resolveType: (value) => {
return value.kind
}
但实际上我们可以依靠 resolveType
和 isTypeOf
的默认实现做得更好:
resolve: () => {
return {
numberOfPaws: 4,
__typename: 'Dog',
}
}
通过像这样显式 returning __typename
,我们实际上可以 完全省略定义 resolveType
。但是,请记住,这又会产生对解析器的依赖。在可能的情况下,您应该倾向于将 resolveType
与 instanceof
检查一起使用,而不是将 resolveType
与您的解析器逻辑分离。
我正在尝试弄清楚如何访问 retrieveRowsWithoutLocations
的 args
字段。但是,我什至不确定 UnionType 的 resolveType
函数中的 value
参数是什么。
我正在查看文档 https://graphql.org/graphql-js/type/#graphqluniontype,但它非常简短,没有详细说明从何处获取该信息。我试过查看其他来源,但它们不是 graphql-js。
我想做的是访问 args.type
并检查它的值,然后允许联合决定它应该 return.
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
)内的任何解析器参数。当一个字段被解析时,解析器 returns 一些值,或者一个将解析为该值的 Promise。对于 return 输出类型、接口或联合的字段,该值应该是 JavaScript 对象。然后将此值传递给 resolveType
,用于确定在运行时响应中实际 return 编辑的类型。
给定一个类似
的架构union Animal = Bird | Fish
type Bird {
numberOfWings: Int
}
type Fish {
numberOfFins: Int
}
type Query {
animal: Animal
}
您可以想象 animal
字段 returns 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}`)
}
如果我们 return 特定 类 实例而不是 return 简单对象,我们可以做得更好:
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}`)
}
无论我们的条件逻辑是什么样子,请记住,我们始终只是在测试由解析器 return 编辑的值,无论它是什么。
如果您不使用 类 并且两个或多个类型共享相同的结构,事情就会变得有点棘手。或者,就像您的情况一样,当区分 属性 (results
) 是一个数组时,因为检查其中一个元素是不行的。想象一下我们的工会看起来像这样:
union Animal = Cat | Dog
type Cat {
numberOfPaws: Int
}
type Dog {
numberOfPaws: Int
}
不幸的是,在这里,我们必须依靠我们的解析器来提供一些额外的信息。例如,我们可以 return 一些任意字段来标识类型:
// Resolver for animal field
resolve: () => {
return {
numberOfPaws: 4,
kind: 'Dog',
}
}
// Union
resolveType: (value) => {
return value.kind
}
但实际上我们可以依靠 resolveType
和 isTypeOf
的默认实现做得更好:
resolve: () => {
return {
numberOfPaws: 4,
__typename: 'Dog',
}
}
通过像这样显式 returning __typename
,我们实际上可以 完全省略定义 resolveType
。但是,请记住,这又会产生对解析器的依赖。在可能的情况下,您应该倾向于将 resolveType
与 instanceof
检查一起使用,而不是将 resolveType
与您的解析器逻辑分离。