我有一个餐厅查询,它返回我的餐厅信息。我的大多数消费者想要的一般信息都来自restaurant-general-info.com。不过,我的消费者可能还想知道其他字段,restaurant-isopen.com,它提供了餐厅目前是否营业以及营业时间。
我已经写了两个属性特定的解析器来处理isOpen和hours,如下所示:
type Query {
restaurant(name: String): Restaurant
}
type Restaurant {
name: String!,
address: String!,
ownerName: String!,
isOpen: Boolean!,
hours: String!
}
Query: {
restaurant: async(parent, {name}) => {
const response = await axios.get(`https://restaurant-general-info.com/${name}`);
return {
address: response.address
ownerName: response.owner
};
}
}
Restaurant: {
isOpen: async(parent) => {
const response = await axios.get(`https://restaurant-isopen.com/${name}`);
return response.openNow;
},
hours: async(parent) => {
const response = await axios.get(`https://restaurant-isopen.com/${name}`);
return response.hoursOfOperation;
}
}
问题是isOpen和hours共享相同的数据源。所以我不想两次打同样的电话。我知道我可以做一个像";开放信息";它包含两个属性,isOpen和hours,但我不希望我的图的消费者需要知道/思考如何以不同的方式分隔这些信息。
是否有一个可以处理多个字段的解析器
前任。
isOpen && hours: async(parent) => {
const response = await axios.get(`https://restaurant-isopen.com/${name}`);
return {
isOpen: response.openNow,
hours: response.hoursOfOperation
}
},
或者有更聪明的方法来处理这个问题吗
注意:API不是真正的
这是一种典型的情况,使用DataLoader将对您有很大帮助。
以下是JS库,以及一些解释:https://github.com/graphql/dataloader
简而言之,实现DataLoader模式允许您批量处理请求,帮助您避免GraphQL中的经典N+1问题,并减轻过度蚀刻,无论这涉及到您的数据库、查询其他服务/API(如您所处(等。
设置DataLoader并批处理您请求的密钥(在本例中为openNow
和hoursOfOperation
(将确保axios GET请求只触发一次。
这里有一篇很棒的Medium文章,可以帮助您直观地了解这是如何在幕后工作的:https://medium.com/@__xuorig__/the-graphql-数据加载器模式-可视化-3064a00f319f