【问题标题】:graphqlj-js union type, access argsgraphqlj-js 联合类型,访问参数
【发布时间】:2019-04-25 18:51:47
【问题描述】:

我试图弄清楚如何访问retrieveRowsWithoutLocationsargs 字段。但是,我什至不确定 UnionType 的 resolveType 函数中的 value 参数是什么。

我正在查看文档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

【问题讨论】:

  • 你能把many_item,`many_list, and many_display_list`的代码包括进来吗?
  • @DanielRearden 不需要......它们只是对象类型。您可以轻松地假装他们是IntStringFloat,这没关系...
  • 我不能这样做,因为标量不能在联合中使用:P 我想看看那个代码来满足我对您的特定用例的回答
  • @DanielRearden 我添加了它,但我认为它没有任何意义,因为我要在查询/突变中访问 args,这似乎不起作用因为resolveType 函数实际上是在读取结果。我将把它拆分成多个查询。

标签: javascript node.js graphql-js


【解决方案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
}

但我们实际上可以通过依赖resolveTypeisTypeOf 的默认实现做得更好:

resolve: () => {
  return {
    numberOfPaws: 4,
    __typename: 'Dog',
  }
}

通过像这样显式返回__typename,我们实际上可以完全省略定义resolveType。但是,请记住,这再次创建了对解析器的依赖。在可能的情况下,您应该倾向于使用 resolveTypeinstanceof 检查来将 resolveType 与解析器逻辑分离。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-11-06
    • 1970-01-01
    • 1970-01-01
    • 2021-07-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多