GraphQL请求JSON解码失败:Go语言测试代码报错求助
解决Go发送GraphQL POST请求的JSON解码错误问题
错误根源分析
- 第一个错误
invalid character 'q' looking for beginning of value:直接发送GraphQL查询字符串(非JSON格式),后端尝试解析JSON时,发现内容不是合法JSON结构(JSON需以{或[开头),导致解析失败。 - 第二个错误
json: cannot unmarshal string into Go value of type graphql.RawParams:错误地将完整的JSON请求体以字符串形式发送(而非JSON对象),后端期望接收包含query等字段的JSON对象,却收到了一个字符串,无法映射到graphql.RawParams类型。
正确解决步骤
1. 定义匹配GraphQL请求的结构体
Go中需要构造符合GraphQL规范的请求体结构,核心包含query字段,可选variables和operationName:
type GraphQLRequest struct { Query string `json:"query"` Variables map[string]interface{} `json:"variables,omitempty"` OperationName string `json:"operationName,omitempty"` }
2. 构造请求体并序列化为JSON
以查询TodoByID为例,构造实例并序列化:
// 构造请求内容,用反引号包裹查询语句避免转义 reqBody := GraphQLRequest{ Query: `query GetTodoByID($id: ID!) { todo(id: $id) { id title completed } }`, Variables: map[string]interface{}{ "id": "1", // 注意ID类型通常为字符串,需与后端定义匹配 }, OperationName: "GetTodoByID", // 可选,部分服务要求指定 } // 序列化为JSON字节 jsonBody, err := json.Marshal(reqBody) if err != nil { t.Fatalf("序列化请求体失败: %v", err) }
3. 发送请求时设置正确的请求头
确保Content-Type为application/json,示例代码:
import ( "bytes" "encoding/json" "net/http" "testing" ) func TestGetTodoByID(t *testing.T) { // 上面的reqBody和jsonBody构造代码... req, err := http.NewRequest("POST", "http://your-graphql-endpoint", bytes.NewBuffer(jsonBody)) if err != nil { t.Fatalf("创建请求失败: %v", err) } // 必须设置正确的Content-Type req.Header.Set("Content-Type", "application/json") client := &http.Client{} resp, err := client.Do(req) if err != nil { t.Fatalf("发送请求失败: %v", err) } defer resp.Body.Close() // 后续处理响应逻辑... }
4. 额外排查点
- 检查查询语句语法:确保和Postman中运行的完全一致,用反引号包裹可避免字符串转义错误。
- 变量类型匹配:比如后端定义
ID!为字符串类型,不要传入数字,需转成字符串。 - 后端要求:部分GraphQL服务强制要求
operationName,需在请求体中指定。
内容的提问来源于stack exchange,提问作者pigfox
相关产品推荐
相关产品推荐

