使用GraphQL的触发器嵌套解析器
我想我在GraphQL解析器的工作方式中遗漏了一些明显的东西。这是我的模式的简化示例(可以包含使用GraphQL的触发器嵌套解析器,graphql,Graphql,我想我在GraphQL解析器的工作方式中遗漏了一些明显的东西。这是我的模式的简化示例(可以包含附加信息的位置): 从“阿波罗服务器”导入{ApolloServer,gql}; 常量typeDefs=gql` 打印位置{ 名字:字符串! 附加信息:附加信息 } 类型附加信息{ foo:String } 类型查询{ 地点:[地点] } `; 以及相关的解析程序: const解析器={ 查询:{ 地点:()=>{ return[{name:'Barcelona'}]; } }, 其他信息:{ foo
附加信息的位置
):
从“阿波罗服务器”导入{ApolloServer,gql};
常量typeDefs=gql`
打印位置{
名字:字符串!
附加信息:附加信息
}
类型附加信息{
foo:String
}
类型查询{
地点:[地点]
}
`;
以及相关的解析程序:
const解析器={
查询:{
地点:()=>{
return[{name:'Barcelona'}];
}
},
其他信息:{
foo:()=>“酒吧”
}
};
const server=new ApolloServer({typeDefs,resolvers});
server.listen().then({url})=>{
log(`API server ready at${url}`);
});
执行基本查询时:
{
places {
name,
additionalInformation {
foo
}
}
}
我总是得到null
作为附加信息
:
{
"data": {
"places": [
{
"name": "Barcelona",
"additionalInformation": null
}
]
}
}
这是我的第一个GraphQL应用程序,我仍然不明白为什么附加信息
解析器没有自动执行。有没有办法让GraphQL知道它必须启动它
我找到了这个解决方法,但我觉得有点棘手:
地点:{
附加信息:()=>{return{};}
}}
让我们暂时假设附加信息
是标量,而不是对象类型:
type Place {
name: String!
additionalInformation: String
}
places
解析器返回的值为:
[{name: 'Barcelona'}]
如果你要做一个类似的查询
query {
places {
name
additionalInformation
}
}
您希望其他信息是什么?它的值将为null,因为由places
解析程序返回的Place
对象上没有additionalInformation
属性
即使我们将附加信息
设为对象类型(如附加信息
),结果也是一样的--附加信息
字段将解析为空。这是因为默认解析程序(在不为字段指定解析程序函数时使用的解析程序)只是查找与父对象上的字段同名的属性。如果找不到该属性,则返回null
您可能已经为AdditionalInformation
(foo
)上的某个字段指定了冲突解决程序,但由于没有必要,因此从未触发此冲突解决程序--整个AdditionalInformation
字段为空,因此跳过关联类型的任何字段的所有冲突解决程序
要理解为什么这是一种可取的行为,请想象一个不同的模式:
type Article {
title: String!
content: String!
image: Image
}
type Image {
url: String!
copyright: String!
}
type Query {
articles: [Article!]!
}
我们有一个数据库,其中包含一个文章
表和一个图像
表作为我们的数据层。文章可能有也可能没有与之关联的图像。我的解析器可能如下所示:
const resolvers = {
Query: {
articles: () => db.getArticlesWithImages()
}
Image: {
copyright: (image) => `©${image.year} ${image.author}`
}
}
假设我们的调用getArticlesWithImages
解析为一篇没有图像的文章:
[{标题:'Foo',内容:'All about foos'}]
作为API的消费者,我请求:
query {
articles {
title
content
image
}
}
图像
字段是可选的。如果我得到一个带有nullimage
字段的文章对象,我就知道数据库中没有关联的图像。作为前端客户端,我知道不渲染任何图像
如果GraphQL为图像返回一个值,不管结果如何,会发生什么情况?显然,我们的解析器会崩溃,因为它不会被传递任何类型的父值。此外,作为API的消费者,我现在必须解析image
的内容,并以某种方式确定某个图像是否与文章相关,我应该对其进行处理
太长,读不下去了
正如您所建议的,这里的解决方案是为additionalInfo
指定一个解析器。您也可以在位置
解析器中简单地返回该值,即:
return [{name: 'Barcelona', additionalInfo: {}}]
实际上,如果模式的形状与底层数据层的形状一致,则在处理真实数据时不太可能遇到此类问题。让我们暂时假设附加信息
是标量,而不是对象类型:
type Place {
name: String!
additionalInformation: String
}
places
解析器返回的值为:
[{name: 'Barcelona'}]
如果你要做一个类似的查询
query {
places {
name
additionalInformation
}
}
您希望其他信息是什么?它的值将为null,因为由places
解析程序返回的Place
对象上没有additionalInformation
属性
即使我们将附加信息
设为对象类型(如附加信息
),结果也是一样的--附加信息
字段将解析为空。这是因为默认解析程序(在不为字段指定解析程序函数时使用的解析程序)只是查找与父对象上的字段同名的属性。如果找不到该属性,则返回null
您可能已经为AdditionalInformation
(foo
)上的某个字段指定了冲突解决程序,但由于没有必要,因此从未触发此冲突解决程序--整个AdditionalInformation
字段为空,因此跳过关联类型的任何字段的所有冲突解决程序
要理解为什么这是一种可取的行为,请想象一个不同的模式:
type Article {
title: String!
content: String!
image: Image
}
type Image {
url: String!
copyright: String!
}
type Query {
articles: [Article!]!
}
我们有一个数据库,其中包含一个文章
表和一个图像
表作为我们的数据层。文章可能有也可能没有与之关联的图像。我的解析器可能如下所示:
const resolvers = {
Query: {
articles: () => db.getArticlesWithImages()
}
Image: {
copyright: (image) => `©${image.year} ${image.author}`
}
}
假设我们的调用getArticlesWithImages
解析为一篇没有图像的文章:
[{标题:'Foo',内容:'All about foos'}]
作为API的消费者,我请求:
query {
articles {
title
content
image
}
}
图像
字段是可选的。如果我得到一个带有nullimage
字段的文章对象,我就知道数据库中没有关联的图像。作为前端客户端,我知道不渲染任何图像
会发生什么