使用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
相关产品推荐
相关产品推荐

