graphqlj-js union类型,访问args

问题描述 投票:1回答:1

我正在试图弄清楚如何访问argsretrieveRowsWithoutLocations字段。但是,我甚至不确定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

javascript node.js graphql-js
1个回答
1
投票

您无法直接访问resolveType(或isTypeOf)中的任何解析器参数。解析字段后,解析程序将返回一些值,或者将解析为该值的Promise。对于返回输出类型,接口或联合的字段,此值应为JavaScript对象。然后将此值传递给resolveTypeunion 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

但是,依靠isTypeOfresolve: () => { return { numberOfPaws: 4, __typename: 'Dog', } } 的默认实现,我们实际上可以做得更好:

__typename

通过像这样显式返回resolveType,我们实际上可以省略完全定义resolveType。但是,请记住,再次,这会对解析程序产生依赖关系。在可能的情况下,您应该倾向于使用instanceofresolveType检查,而不是将qazxswpoi与解析器逻辑分离。

© www.soinside.com 2019 - 2024. All rights reserved.