POST之前GoLang中的GZip JSON有效负载

I have a JSON object of type []byte that I created from a struct using json.Marshal. I want to GZip the JSON before posting it to my endpoint. The following does not work:

gz := gzip.NewWriter(myJSON)

because []byte does not implement io.Writer.

Is there some very simple way I can do this once I already have my JSON created?

Compress to a buffer and post that buffer.

 var buf bytes.Buffer
 gz := gzip.NewWriter(&buf)
 gz.Write(myJSON)
 gz.Close()

Because a *bytes.Buffer statisifies the io.Reader interface, you can use the buffer directly when creating the request.

 req, err := http.NewRequest("POST", url, &buf)
 if err != nil {
     // handle error
 }
 req.Header.Set("Content-Encoding", "gzip")
 req.Header.Set("Content-Type", "application/json; charset=utf-8")

The best option is to stream your JSON marshaling to your gzip writer:

func compressJSON(w io.Writer, i interface{}) error {
    gz := gzip.NewWriter(w)
    if err := json.NewEncoder(gz).Encode(i); err != nil {
        return err
    }
    return gz.Close()
}

This has the advantage of not buffering your json in memory temporarily, so it will be faster and use less RAM.

If you need this as an io.Reader, such as for the body of an HTTP request, you can use a pipe to do the conversion:

r, w := io.Pipe()
go func() {
    err := compressJSON(w, someObject)
    w.CloseWithError(err)
}()
req, err := http.NewRequest("POST", "http://example.com/", r)