GraphQL 动态查询构建 [英] GraphQL dynamic query building

查看:53
本文介绍了GraphQL 动态查询构建的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 GraphQL 服务器,它能够为指定来源(例如,传感器数据)提供时间序列数据.获取传感器数据的示例查询可能是:

I have a GraphQL server which is able to serve timeseries data for a specified source (for example, sensor data). An example query to fetch the data for a sensor might be:

query fetchData {
    timeseriesData(sourceId: "source1") {
      data {
        time
        value
      }
    }
}

在我的前端,我希望允许用户选择 1 个或多个来源并显示一个图表,每个来源都有一条线.通过使用这样的查询,这似乎是可能的:

In my frontend, I want to allow the user to select 1 or more sources and show a chart with a line for each one. It seems like this would be possible by using a query like this:

query fetchData {
    series1: timeseriesData(sourceId: "source1") {
      data {
        time
        value
      }
    }
    series2: timeseriesData(sourceId: "source2") {
      data {
        time
        value
      }
    }
}

大多数 GraphQL 教程似乎都专注于静态查询(例如,唯一改变的是变量,而不是请求的实际形状) - 但在我的情况下,我需要查询本身 是动态的(我选择的每个 ID 都有一个 timeseriesData 请求).

Most GraphQL tutorials seem to focus on static queries (e.g. where the only thing that is changing is the variables, but not the actual shape of the request) - but in my case I need the query itself to be dynamic (one timeseriesData request for each of my selected ids).

我有以下限制:

  1. 修改服务器的架构不是一个选项(例如,我无法将一组 ID 传递给解析器)
  2. 我的查询是使用模板字符串指定的,例如gql`...`
  3. 我不想手动将查询构建为字符串,因为这似乎是灾难的秘诀,并且意味着我将失去所有工具优势(例如自动完成、语法突出显示、linting)

我使用的堆栈是:

  • Apollo 客户端(特别是 apollo-angular)
  • 角度
  • 打字稿
  • graphql-tag(用于定义查询)

理想情况下,我想要做的是将两个查询合并为一个,以便我可以按照第一个示例定义它们,然后将它们连接到一个抽象层中,这样我就可以得到一个查询,例如通过网络发送的第二个示例.

Ideally, what I want to do is have some way of merging two queries into one, so that I can define them as per the first example but then join them together in an abstraction layer so that I get a single query like the second example to be sent over the wire.

但是,我不确定如何实现这一点,因为 graphql-tag 正在将查询解析为 AST,我正在努力了解以这种方式操作查询是否可行.

However I'm not sure how to achieve this because graphql-tag is parsing the query into an AST and I'm struggling to understand whether it's feasable to manipulate the query in this way.

有哪些技术可以生成这样的动态查询,其中查询的形状事先未知?

What techniques are there for generating a dynamic query like this, where the shape of the query is not known upfront?

推荐答案

可以使用fragment来定义公共字段,以及变量绑定@include(if: Boolean)@skip(if: Boolean) 该片段上的指令以获取在执行时已知的动态字段.

You can use fragment to define common fields, and variable bound @include(if: Boolean) and @skip(if: Boolean) directives on that fragment to get dynamic fields that are known at execution time.

根据规范,最好避免手动字符串插值来构建动态查询.

According to spec, it is best to avoid manual string interpolation to construct dynamic queries.

指令1 可以包含或跳过基于作为查询变量传递的布尔表达式的字段.指令可以附加到字段或片段包含,并且可以以服务器希望的任何方式影响查询的执行.

Directives1 make it possible to include or skip a field based on a boolean expression passed as a query variable. A directive can be attached to a field or fragment inclusion, and can affect execution of the query in any way the server desires.

query Hero($episode: Episode, $withFriends: Boolean!) {
  hero(episode: $episode) {
    name
    friends @include(if: $withFriends) {
      name
    }
  }
}

在变量中:

{
  "episode": "JEDI",
  "withFriends": false
}

当然,您可以像在第二个示例中一样发送命名查询.客户端将自动批处理请求.

Of course you can send named queries as you did in your second example. Clients will batch the requests automatically.

这篇关于GraphQL 动态查询构建的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆