Go语言 GraphQL请求json请求正文无法解码:

yrdbyhpb  于 2022-12-16  发布在  Go
关注(0)|答案(1)|浏览(163)

我是GraphQL的新手,所以我看了看我的 Postman 请求。这是原始的 Postman 请求。

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
    }
}"

我尝试了以下方法

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 {

有什么想法吗?

2ul0zpep

2ul0zpep1#

标准的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) // or handle it however you would otherwise
}
request, err := http.NewRequest("POST", url, jsonData)
...

您可能会发现,将响应数据json.Unmarshal()到具有标准格式的结构中同样有用,Data字段与查询的形状匹配。

相关问题