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

使用Golang调用Hasura GraphQL查询时where参数报错求助

问题

使用Golang调用Hasura发起GraphQL查询时,无法正确携带where条件,收到错误:

graphql: expected an object for type 'popular_streamers_bool_exp', but found a string

我的GraphQL查询语句:

query MyQuery($where: popular_streamers_bool_exp!) {
    popular_streamers(where: $where) {
        first_name
        last_name
    }
}

对应的Go代码片段:

type conditions struct {
    FollowersCount struct {
        Gte int `json:"_gte"`
    } `json:"followers_count"`
    Gender struct {
        Eq string `json:"_eq,omitempty"`
    } `json:"gender,omitempty"`
}
condition := conditions{}
condition.FollowersCount.Gte = 1
condition.Gender.Eq = "Male"

data, _ := json.Marshal(condition)
解决方案

核心问题:你把json.Marshal生成的字符串直接作为where参数的值传递了,但Hasura期望的是JSON对象类型的变量,而非字符串类型。

正确做法

不要手动单独序列化condition结构体,而是将其直接作为变量值传入GraphQL请求的变量集合中,让客户端库或整体请求体序列化来处理类型转换。

方案1:使用GraphQL客户端库(推荐)

以graphql-go客户端为例,修改后的代码:

import (
    "context"
    "github.com/graph-gophers/graphql-go"
)

// 定义响应结构体
type Streamer struct {
    FirstName string `json:"first_name"`
    LastName  string `json:"last_name"`
}

var resp struct {
    PopularStreamers []Streamer `json:"popular_streamers"`
}

// 初始化客户端
client := graphql.NewClient("https://your-hasura-instance/v1/graphql", nil)

// 定义查询语句
query := `
query MyQuery($where: popular_streamers_bool_exp!) {
    popular_streamers(where: $where) {
        first_name
        last_name
    }
}
`

// 构造查询条件
condition := conditions{}
condition.FollowersCount.Gte = 1
condition.Gender.Eq = "Male"

// 直接将condition作为变量值传入
variables := map[string]interface{}{
    "where": condition,
}

// 执行查询
err := client.Query(context.Background(), query, &resp, variables)
if err != nil {
    // 处理错误逻辑
}

方案2:手动构造HTTP请求

如果是自己发送HTTP POST请求,需要将整个GraphQL请求体(包含query和variables)统一序列化,而非单独序列化where参数:

import (
    "bytes"
    "encoding/json"
    "net/http"
)

// 定义GraphQL请求体结构
type GraphQLRequest struct {
    Query     string                 `json:"query"`
    Variables map[string]interface{} `json:"variables"`
}

// 构造请求体
reqBody := GraphQLRequest{
    Query: query,
    Variables: map[string]interface{}{
        "where": condition,
    },
}

// 序列化整个请求体
requestData, err := json.Marshal(reqBody)
if err != nil {
    // 处理序列化错误
}

// 发送POST请求
req, err := http.NewRequest("POST", "https://your-hasura-instance/v1/graphql", bytes.NewBuffer(requestData))
if err != nil {
    // 处理请求构造错误
}
req.Header.Set("Content-Type", "application/json")

client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
    // 处理请求发送错误
}
defer resp.Body.Close()

关键注意点

  • 你的conditions结构体的JSON标签是正确的,和Hasura生成的popular_streamers_bool_exp字段匹配,无需调整。
  • 永远不要单独序列化GraphQL变量中的对象类型参数,否则会将其转为字符串,导致类型不匹配错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 05:46:06