为什么GraphQL不调用嵌套类型为 Starring 的解析器?
我可以将文件和文件夹加为我的收藏夹。所以我的架构很简单:
type File {
id: ID!,
name: String,
starring: Starring
}
type Folder {
id: ID!,
name: String,
starring: Starring
}
type Starring {
isStarred: Boolean!
}
我为Starring找出了两种避免代码重复的方法。但是,我想知道为什么GraphQL不够巧,无法首先调用Starring解析器(没有从包装的File解析器中引用)。
到达星标解析器的第一种可能方法:
// File.js
export default {
id: obj => { obj.id.replace('/file/', '') }
name: obj => { obj.name.toUpperCase() }
// why do I need to pass the obj so that the Starring resolver is called?
starring: obj => obj
}
// Starring.js
export default {
isStarred: obj => obj.isStarred
}
避免重复的第二种可能方法:
// File.js
import starring from './starring'
export default {
// feels like wrong approach when I just spread the starring object
...starring
id: obj => { obj.id.replace('/file/', '') }
name: obj => { obj.name.toUpperCase() }
}
答案 0 :(得分:0)
GraphQL不够“聪明”,无法调用Starring
解析器,因为父对象的结构与您的架构不匹配。根据您的模式,这是GraphQL返回的File
对象的样子:
{
id: 'string',
name: 'string',
starring: {
isStarred: false
}
}
在您的代码中,传递给File
解析器的父对象看起来像这样:
{
id: 'string'
name: 'string'
isStarred: false
}
因此,您可以任一展平您的架构:
type Folder {
id: ID!,
name: String,
isStarred: Boolean!
}
在这种情况下,您用于Folder
的解析器将如下所示:
export default {
id: obj => obj.id.replace('/file/', '')
name: obj => obj.name.toUpperCase()
// no need to add resolver for isStarred -- default resolver will handle it for you
}
另一个选择是操纵作为父对象传递给File
类型的解析器的对象。例如,如果您有一个查询在其解析程序中返回文件数组,则可以遍历每个查询并将isStarred
属性嵌套在starring
内,然后再返回数组。
后一种选择与将父对象传递到Starring
解析器一样难看。归根结底,您最好将架构展平以匹配正在使用的数据的形状。