Graphql 中的包装器类型是啥?
Posted
技术标签:
【中文标题】Graphql 中的包装器类型是啥?【英文标题】:What is a wrapper type in Graphql?Graphql 中的包装器类型是什么? 【发布时间】:2020-03-13 16:10:42 【问题描述】:我正在学习 GraphQl 官方文档。
当我来到章节自省 link here
我遇到了一种叫做包装器类型的东西。
输入:
__type(name: "Droid")
name
fields
name
type
name
kind
输出:
"data":
"__type":
"name": "Droid",
"fields": [
"name": "id",
"type":
"name": null, # here
"kind": "NON_NULL"
,
"name": "name",
"type":
"name": null, # here
"kind": "NON_NULL"
,
"name": "friends",
"type":
"name": null, # here
"kind": "LIST"
,
"name": "friendsConnection",
"type":
"name": null, # here
"kind": "NON_NULL"
,
"name": "appearsIn",
"type":
"name": null, # here
"kind": "NON_NULL"
,
"name": "primaryFunction",
"type":
"name": "String", # normal here
"kind": "SCALAR"
]
文章声称那些类型为的字段的名称为NULL,因为它是一种“包装器”类型的NON_NULL
谁能解释一下包装器类型到底是什么?最好提供一个示例或代码来解释为什么 primaryFunction 有名字而其他人没有。
【问题讨论】:
【参考方案1】:来自spec:
到目前为止,所有类型都被假定为可为空和单数:例如标量字符串返回 null 或单数字符串。
一个 GraphQL 模式可以描述一个字段代表另一个类型的列表;出于这个原因提供了 List 类型,并包装了另一种类型。
同样,Non-Null 类型包装了另一种类型,并表示结果值永远不会为 null(并且错误不会导致 null 值)。
这两种类型被称为“包装类型”;非包装类型称为“命名类型”。包装类型具有底层命名类型,通过不断解包装类型直到找到命名类型来找到。
一个包装类型包装另一个类型,它本身也可能是一个包装类型。但是,当您“解包”每个包装类型时,最终您必须找到所有这些包装类型都与之关联的命名类型。换句话说,包装类型永远不能单独使用。包装类型始终只有一个与之关联的命名类型。
自省,要确定包裹类型是包裹什么类型,使用ofType
字段:
__schema
types
name
ofType
name
您可以进一步为潜在的“展开”类型添加额外的级别:
__schema
types
name
ofType
name
ofType
name
至于为什么内省没有显示这些类型的名称,这是因为规范明确禁止它。查看List 类型的部分:
列表表示 GraphQL 中的值序列。 List 类型是一个类型修饰符:它在 ofType 字段中包装了另一个类型实例,该字段定义了列表中每个项目的类型。
字段
kind 必须返回 __TypeKind.LIST。 ofType:任何类型。 所有其他字段必须返回 null。
【讨论】:
【参考方案2】:这是我前几天完成的教程中的一些 sn-p。它表示用 GraphQLNonNull 运算符包装的类型(它用于服务器端):
const ContestStatusType = require('./contest-status')
const NameType = require('./name')
module.exports = new GraphQLObjectType(
name: 'ContestType',
fields:
id: type: GraphQLID ,
description: type: GraphQLString ,
status: type: new GraphQLNonNull(ContestStatusType) ,
createdAt: type: new GraphQLNonNull(GraphQLString) ,
createdBy: type: new GraphQLNonNull(GraphQLString) ,
names:
type: new GraphQLList(NameType),
resolve(obj, args, loaders, pgPool )
return loaders.namesForContestIds.load(obj.id);
return pgdb(pgPool).getNames(obj)
);
【讨论】:
以上是关于Graphql 中的包装器类型是啥?的主要内容,如果未能解决你的问题,请参考以下文章