英文:
GraphQL request json request body could not be decoded:
问题
我对GraphQL还不太熟悉,所以我查看了我的Postman请求。
这是原始的Postman请求。
请求头
Content-Type: application/json
User-Agent: PostmanRuntime/7.29.2
Accept: */*
Cache-Control: no-cache
Postman-Token: e3239924-6e8a-48b9-bc03-3216ea6da544
Host: localhost:4000
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
Content-Length: 94
请求体
query: "query {
getTodo(todoId:3) {
id
text
done
}
}"
我尝试了以下代码
var url = "http://localhost:4000/query"
func TestGetTodoByID(t *testing.T) {
jsonData := `query {
getTodo(todoId:3) {
id
text
done
}
}`
fmt.Println(jsonData)
request, err := http.NewRequest("POST", url, bytes.NewBuffer([]byte(jsonData)))
request.Header.Set("Content-Type", "application/json")
request.Header.Set("Content-Length", fmt.Sprint(len(jsonData)))
client := &http.Client{Timeout: time.Second * 10}
response, err := client.Do(request)
defer response.Body.Close()
if err != nil {
fmt.Printf("The HTTP request failed with error %s\n", err)
}
data, err := io.ReadAll(response.Body)
if err != nil {
fmt.Printf("Error reading response with error %s\n", err)
}
responseBody := string(data)
if status := response.StatusCode; status != http.StatusOK {
t.Errorf("handler returned wrong status code: got %v want %v",
status, http.StatusOK)
}
expected := `{
"data": {
"getTodo": {
"id": 3,
"text": "qwert333 hello",
"done": true
}
}
}`
if responseBody != expected {
t.Errorf("handler returned unexpected body: got %v want %v",
responseBody, expected)
}
}
然后我得到了以下错误:
api_test.go:41: handler returned wrong status code: got 400 want 200
api_test.go:54: handler returned unexpected body: got {"errors":[{"message":"json request body could not be decoded: invalid character 'q' looking for beginning of value body:query {\n getTodo(todoId:3) {\n id\n text\n done\n }\n}"}],"data":null} want {
然后我也尝试了在Postman控制台中找到的代码
jsonData := `"query":"query {
getTodo(todoId:3) {
id
text
done
}
}"`
这给了我一个稍微不同的错误
api_test.go:41: handler returned wrong status code: got 400 want 200
api_test.go:54: handler returned unexpected body: got {"errors":[{"message":"json request body could not be decoded: json: cannot unmarshal string into Go value of type graphql.RawParams body:\"query\":\"query {\n getTodo(todoId:3) {\n id\n text\n done\n }\n}\""}],"data":null} want {
有什么想法吗?
英文:
I am new to GraphQL so I looked at my Postman request.
This is the raw Postman request.
Request Headers
Content-Type: application/json
User-Agent: PostmanRuntime/7.29.2
Accept: */*
Cache-Control: no-cache
Postman-Token: e3239924-6e8a-48b9-bc03-3216ea6da544
Host: localhost:4000
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
Content-Length: 94
Request Body
query: "query {
getTodo(todoId:3) {
id
text
done
}
}"
I tried the following
var url = "http://localhost:4000/query"
func TestGetTodoByID(t *testing.T) {
jsonData := `query {
getTodo(todoId:3) {
id
text
done
}
}`
fmt.Println(jsonData)
request, err := http.NewRequest("POST", url, bytes.NewBuffer([]byte(jsonData)))
request.Header.Set("Content-Type", "application/json")
request.Header.Set("Content-Length", fmt.Sprint(len(jsonData)))
client := &http.Client{Timeout: time.Second * 10}
response, err := client.Do(request)
defer response.Body.Close()
if err != nil {
fmt.Printf("The HTTP request failed with error %s\n", err)
}
data, err := io.ReadAll(response.Body)
if err != nil {
fmt.Printf("Error reading response with error %s\n", err)
}
responseBody := string(data)
if status := response.StatusCode; status != http.StatusOK {
t.Errorf("handler returned wrong status code: got %v want %v",
status, http.StatusOK)
}
expected := `{
"data": {
"getTodo": {
"id": 3,
"text": "qwert333 hello",
"done": true
}
}
}`
if responseBody != expected {
t.Errorf("handler returned unexpected body: got %v want %v",
responseBody, expected)
}
}
Then I got the following error:
api_test.go:41: handler returned wrong status code: got 400 want 200
api_test.go:54: handler returned unexpected body: got {"errors":[{"message":"json request body could not be decoded: invalid character 'q' looking for beginning of value body:query {\n getTodo(todoId:3) {\n id\n text\n done\n }\n}"}],"data":null} want {
Then I also tried exactly what I found in the Postman console
jsonData := `"query":"query {
getTodo(todoId:3) {
id
text
done
}
}"`
This gave me a slightly different error
api_test.go:41: handler returned wrong status code: got 400 want 200
api_test.go:54: handler returned unexpected body: got {"errors":[{"message":"json request body could not be decoded: json: cannot unmarshal string into Go value of type graphql.RawParams body:\"query\":\"query {\n getTodo(todoId:3) {\n id\n text\n done\n }\n}\""}],"data":null} want {
Any ideas?
答案1
得分: 1
标准的GraphQL JSON格式实际上是一个JSON对象。在Go语言环境中,最简单的方法是使用encoding/json
包中的结构体进行创建。(你可以寻找一个专门的GraphQL客户端包,其中已经预定义了这个结构体。)
例如,你可以为该结构体创建一个最简形式的结构体:
type GraphQLRequest struct{
Query string `json:"query"`
Variables map[string]interface{} `json:"variables,omitempty"`
}
然后创建该结构体的实例并进行序列化:
query := `query GetTodo($id: ID!) {
getTodo(todoId: $id) { id, name, done }
}`
request := GraphQLRequest{
Query: query,
Variables: map[string]interface{}{
"id": 3,
}
}
jsonData, err := json.Marshal(request)
if (err != nil) {
panic(err) // 或者以其他方式处理错误
}
request, err := http.NewRequest("POST", url, jsonData)
...
你可能会发现,将响应数据使用json.Unmarshal()
解析为一个具有标准格式的结构体同样很有用,其中Data
字段与你的查询形状相匹配。
英文:
The standard GraphQL JSON format is actually a JSON object. In a Go context, the easiest way to create this is with a structure annotated for the encoding/json
package. (You may go looking for a dedicated GraphQL client package that has this structure predefined.)
So for example you might create a structure for the minimal form of that structure
type GraphQLRequest struct{
Query string `json:"query"`
Variables map[string]interface{} `json:"variables,omitempty"`
}
and then create an instance of that structure and serialize it
query := `query GetTodo($id: ID!) {
getTodo(todoId: $id) { id, name, done }
}`
request := GraphQLRequest{
Query: query,
Variables: map[string]interface{}{
"id": 3,
}
}
jsonData, err := json.Marshal(request)
if (err != nil) {
panic(err) // or handle it however you would otherwise
}
request, err := http.NewRequest("POST", url, jsonData)
...
You may find it similarly useful to json.Unmarshal()
the response data into a structure that has the standard format, with a Data
field matching the shape of your query.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论