GraphQL动态查询构建
我有一个GraphQL服务器,它能够为指定源(例如传感器数据)提供timeseries数据。获取传感器数据的查询示例可能是:GraphQL动态查询构建,graphql,apollo,apollo-client,graphql-tag,Graphql,Apollo,Apollo Client,Graphql Tag,我有一个GraphQL服务器,它能够为指定源(例如传感器数据)提供timeseries数据。获取传感器数据的查询示例可能是: query fetchData { timeseriesData(sourceId: "source1") { data { time value } } } 在我的前端,我希望允许用户选择一个或多个源,并显示一个图表,每个图表都有一条线。使用这样的查询似乎可以做到这一点: query fetchD
query fetchData {
timeseriesData(sourceId: "source1") {
data {
time
value
}
}
}
在我的前端,我希望允许用户选择一个或多个源,并显示一个图表,每个图表都有一条线。使用这样的查询似乎可以做到这一点:
query fetchData {
series1: timeseriesData(sourceId: "source1") {
data {
time
value
}
}
series2: timeseriesData(sourceId: "source2") {
data {
time
value
}
}
}
大多数GraphQL教程似乎侧重于静态查询(例如,唯一改变的是变量,而不是请求的实际形状),但在我的例子中,我需要查询本身是动态的(每个选定ID的一次数据请求)
我有以下限制:
- 阿波罗客户机(特别是阿波罗角机)
- 棱角的
- 打字稿
- graphql标记(用于定义查询)
查询片段
首先,让我们为每个timeSeries
创建一个片段
,请检查您的timeSeries查询类型,我将其称为timeseriesDataQuery
const series1Q = gql`
fragment series1 on timeseriesDataQuery {
series1: timeseriesData(sourceId: "source1") {
data {
time
value
}
}
}
}
const series2Q = gql`
fragment series2 on timeseriesDataQuery {
series2: timeseriesData(sourceId: "source2") {
data {
time
value
}
}
}
}
然后在查询中缝合它们:
export const mainQuery = gql`
query fetchData {
...series1
...series2
}
${series1Q}
${series2Q}
`
您可以使用fragment定义公共字段,并在该片段上使用变量绑定的@include(if:Boolean)
和@skip(if:Boolean)
指令来获取执行时已知的动态字段
根据规范,最好避免手动字符串插值来构造动态查询
指令可以基于作为查询变量传递的布尔表达式包含或跳过字段。指令可以附加到字段或片段包含,并且可以以服务器希望的任何方式影响查询的执行
query Hero($episode: Episode, $withFriends: Boolean!) {
hero(episode: $episode) {
name
friends @include(if: $withFriends) {
name
}
}
}
在变量中:
{
"episode": "JEDI",
"withFriends": false
}
当然,您可以像在第二个示例中那样发送命名查询。客户端将自动批处理请求。我认为当用户动态选择传感器时,即使您在开发时(不是运行时)不知道传感器,您也别无选择,只能使用字符串功能
mainQueryStr
是查询的字符串值(用于处理问题的动态性)
然后在传感器上循环并用每个传感器的id替换$sourceId
// You have to remove the query wrapper first
// Then replace sensor id
const sensorsQueries = sensors.map(sid => mainQueryStr
.split(`\n`)
.slice(1, 7)
.replace(`$sourceId`, sid)
)
然后您应该加入sensorQueries并创建新的GraphQL查询
const finalQuery = gql`
query fetchData {
${sensorsQueries.join(`\n`)}`
};
在这种情况下,您可以使用诸如自动完成、语法突出显示和。。。
对于mainQuery
查询,而不是finalQuery
(因为您动态创建了这个)快速问题,如果我有多个片段,我不知道长度,我可以这样构造mainQuery吗?比如,动态地将多个片段添加到查询中?@Evilsanta,只要您在主查询中动态地定义反片段及其引用,我认为这是可能的。@Matt Wilson您有没有想出解决方案?我也有同样的情况。我从另一个服务获得了一个ID数组,对于每个ID,我需要调用一个graphql查询,并希望以1或in的形式调用它们batches@Mr.7嗨,我正在使用Apollo和Apollo客户端,发现这个“BatchHttpLink”是一个方法。我把我的解决方案放在这里:Apollo文档:在客户端,您只是创建一个到(Apollo)graphql服务器的新连接,该服务器在批量发送一个或多个请求之前等待一段时间。在过去的几个月里,它一直在处理100次用户静默,没有任何问题。hanks@user3067684我来看看:)
const finalQuery = gql`
query fetchData {
${sensorsQueries.join(`\n`)}`
};