You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rust gql_client查询GraphQL端点报metric前语法错误

问题原因

报错本质是GraphQL查询语句语法不符合规范,同时存在后续反序列化类型不匹配的隐患:

  1. 字段参数位置错误:GraphQL中query/mutation关键字后紧跟的操作名括号内,仅支持定义$变量名: 类型格式的查询变量,不能直接传入字段参数字面量。你将getMetric字段的metric: "dev_activity"参数错放到了操作声明位置,解析器读到非变量格式的metric字段直接抛出语法错误。
  2. 查询结构错位:timeseriesData是getMetric字段下的子字段,你没有将其嵌套在getMetric的选择集(花括号范围)内,层级关系完全错误。
  3. 类型定义不匹配:接口返回的value字段是浮点数格式(如1281.0),你在Rust结构体中定义为i64整数类型,即使查询语法修复,后续反序列化也会失败。
  4. 冗余声明:Rust 2021 edition不需要手动写extern crate serde_derive;声明,该语句可直接删除。
修复方案

1. 修正GraphQL查询语句

将字段参数放回对应字段后,补全正确的嵌套结构:

let query = r#"
query {
  getMetric(metric: "dev_activity") {
    timeseriesData(
      slug: "ethereum"
      from: "2020-02-10T07:00:00Z"
      to: "2020-03-10T07:00:00Z"
      interval: "1w"
    ) {
      datetime
      value
    }
  }
}
"#;

2. 修正结构体字段类型

将TimeseriesDatum的value字段类型从i64改为f64,匹配接口返回格式:

#[derive(Debug, Serialize, Deserialize)]
pub struct TimeseriesDatum {
    pub datetime: String,
    pub value: f64,
}

3. 优化错误处理

替换连续unwrap()逻辑,避免无意义panic:

let response = client.query::<DevActivity>(query).await?
    .ok_or("接口返回空响应")?;
修复后完整代码
use gql_client::Client;
use serde::{Deserialize, Serialize};

#[derive(Debug, Serialize, Deserialize)]
pub struct DevActivity {
    pub data: Data,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct Data {
    #[serde(rename = "getMetric")]
    pub get_metric: GetMetric,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct GetMetric {
    #[serde(rename = "timeseriesData")]
    pub timeseries_data: Vec<TimeseriesDatum>,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct TimeseriesDatum {
    pub datetime: String,
    pub value: f64,
}

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let query = r#"
query {
  getMetric(metric: "dev_activity") {
    timeseriesData(
      slug: "ethereum"
      from: "2020-02-10T07:00:00Z"
      to: "2020-03-10T07:00:00Z"
      interval: "1w"
    ) {
      datetime
      value
    }
  }
}
"#;

    let endpoint = "https://api.santiment.net/graphql";
    let client = Client::new(endpoint);

    let response = client.query::<DevActivity>(query).await?
        .ok_or("接口返回空内容")?;

    for data in &response.data.get_metric.timeseries_data {
        println!("datetime {}, value {}", data.datetime, data.value)
    }
    Ok(())
}
后续排查方向

如果修复后仍有问题,按以下顺序检查:

  • 先将写好的GraphQL语句放到对应服务的调试 playground 中验证,确认语句本身可以正常返回数据再放入代码
  • 检查本地网络是否能正常访问目标API端点,无拦截、超时问题
  • 核对serde的rename配置与接口返回字段名完全一致,注意大小写敏感
  • 确认依赖版本无兼容性问题,当前使用的gql_client 1.0.4版本兼容上述写法

内容的提问来源于stack exchange,提问作者0xsegfault

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 09:57:16