在graphql我想使用提供给父venues
查询的coordiantes
构建movies
查询,而在events
我想要使用父地点ID,例如
{
movies(coordinates: {latitude: 51.509865, longitude: -0.118092}) {
id,
venues (coordinates: [parent query coordinates]) {
id,
events (coordinates: [parent query coordinates], venueId: [parent query venue]) {
id
}
}
}
}
如何引用父查询参数/结果?
答案 0 :(得分:1)
您尝试实现的第一件事(重用参数)可以使用GraphQL variables完成。然而,据我所知,第二件事(重复使用输出值作为输入)无法实现。 然而,两者都听起来像你的类型关系没有正确定义。让我们更详细地看一下这些要点。
TL; DR 变量是重用参数的关键概念,但在OP描述的情况下可能并不理想。请参阅下面的答案的第二部分。我将其留在这里以提供详细信息。
GraphQL variables非常适合定义一次参数并多次使用它们。
使用swapi-graphql
的最小示例如下所示:
query SomePeopleAndCompatriots($numberOfResults: Int) {
allPeople(first: $numberOfResults) {
name
homeworld {
name
residents(first: $numberOfResults) {
name
}
}
}
}
同时声明以下变量:
{ "numberOfResults": 3 }
实际上,此API实现了notions of node and edges,因此实际查询有点复杂,但play with it可以随意使用。
This reference将为您提供有关如何使用GraphQL.js使用参数的更多详细信息,但由于您未提供与您的架构声明相对应的代码,因此您需要调整详细信息。
在您的情况下,在我看来,您已将coordinates
定义为输入类型。我们假设您调用了CoordinatesInput
,现在您的查询看起来像(有意省略venueId
,请参阅下面的其他答案):
query MoviesAndVenuesAndEvents($coordinates: CoordinatesInput) {
movies(coordinates: $coordinates) {
id
venues (coordinates: $coordinates) {
id
events (coordinates: $coordinates) {
id
}
}
}
}
传递相应的变量:
{ "coordinates": { "latitude": 51.509865, "longitude": -0.118092 } }
这可以达到您的预期,但这可能不是最佳途径,我们将在下面看到。
使用我的信息,您的查询,看起来movies
,venues
和events
背后的类型彼此不了解。这意味着您的架构无法充分利用GraphQL的所有功能。将您的架构视为树,其中events
是venue
的孩子,venues
是movies
的孩子。
在venueId
的情况下,您甚至不需要它。
让我们对您的架构声明做一些假设。您的VenueType
将如下所示:
const VenueType = new GraphQLObjectType({
name: 'Venue'
id: /* ... */,
// ...
events: {
type: new GraphQLList(EventType),
description: 'All events happening at this venue',
resolve: venue => venue.getEvents()
)
});
当您对events
的所有结果进行venues
查询时,实际上请求解析程序调用您可以操作的给定getEvents()
上的venue
。我不了解您的实施情况,但它可以只执行venue.events
或Event.findAllByVenue(venue.id)
等。您可以确保只检索特定地点的事件,而不是所有事件在你的存储空间。
This example将为您提供有关如何执行此操作的更多详细信息。
同样,MovieType
应该venues
解析为movie => movie.getVenues()
,这就是为什么我的答案的第一部分不适合您的情况。最后,您的查询应如下所示:
query MoviesAndVenuesAndEvents($coordinates: CoordinatesInput) {
movies(coordinates: $coordinates) {
id
venues {
id
events {
id
}
}
}
}
基本上说:"在给定这些坐标的情况下获取所有电影,并为每部电影提供所有场地和所有这些场地的活动"。
如果您想获得的是在给定区域内播放的所有电影(目前仅关注电影和场地,但您可以将其推断为事件),那么您的查询应该是:
venues(coordinates: $coordinates) {
id
movies
}
但是最后一个例子可能会给你重复的东西,你必须在客户端上展平。要首先关注电影,您可以使用前面的示例,确保您的movies
解析器仅检索传递坐标的电影。再次对后端进行完整的假设,它可能如下所示:
resolve: coordinates => allMovies.filter(movie =>
movie.venues.some(venue => venue.coordinates === coordinates)
)