带有身体Go的Http POST请求

时间:2019-09-27 23:38:45

标签: http go

我想使用Go net/http库使用主体构造HTTP POST请求。

我用来构造http请求的函数如下:docs

http.NewRequest(method string, url string, body io.Reader)

我想出了两种解决方案,但我试图看看哪种解决方案更惯用且可扩展以支持不同的身体构造。

Solution #1

bytesObj := []byte(`{"key":"value"}`)
body := bytes.NewBuffer(bytesObj)

Solution #2

bodyMap := map[string]string{"key":"value"}
bodyBytes, _ := json.Marshal(bodyMap)
body := bytes.NewBuffer(bodyBytes)

理想情况下,我会将代码移至辅助函数,以便可以自定义主体的构造。辅助功能将类似于

func constructBody(someArgument) io.Reader {
  return bodyHere
}

2 个答案:

答案 0 :(得分:0)

如果主体已经是字符串,则选项#1对我来说更具吸引力。

如果仅使用键->仅包含字符串的值,则选项#2更好。 但是,当您嵌套struct时,这将变得很麻烦

但是根据我的经验,大多数时候我们都在处理struct。我想使该结构更接近http调用发生的位置。

func main() {
    ctx := context.Background()

    body := struct {
        Key string `json:"key"`
    }{
        Key: "value",
    }

    out, err := json.Marshal(body)
    if err != nil {
        log.Fatal(err)
    }


    req, err := http.NewRequest("POST", "http://example.com", bytes.NewBuffer(out))
    if err != nil {
        log.Fatal(err)
    }

    req = req.WithContext(ctx)

    http.DefaultClient.Do(req)
}

如果该结构在多个地方使用,则可以制作一个包级结构。

答案 1 :(得分:0)

要使其具有更高的可重用性,您可以创建一个JSONReaderFactory,它仅需要几行代码:

func jsonReaderFactory(in interface{}) (io.Reader, error) {
    buf := bytes.NewBuffer(nil)
    enc := json.NewEncoder(buf)
    err := enc.Encode(in)
    if err != nil {
        return nil, fmt.Errorf("creating reader: error encoding data: %s", err)
    }
    return buf, nil
}

Example on playground