POST之前的gzip JSON有效负载

POST之前的gzip JSON有效负载,json,go,gzip,Json,Go,Gzip,我有一个类型为[]byte的JSON对象,它是我使用JSON.Marshal从结构创建的。我想在将JSON发布到我的端点之前对其进行GZip处理。以下操作不起作用: gz := gzip.NewWriter(myJSON) 因为[]字节没有实现io.Writer 一旦我已经创建了JSON,有什么非常简单的方法可以做到这一点吗?压缩到缓冲区并发布该缓冲区 var buf bytes.Buffer gz := gzip.NewWriter(&buf) gz.Write(myJSON)

我有一个类型为
[]byte
的JSON对象,它是我使用
JSON.Marshal
从结构创建的。我想在将JSON发布到我的端点之前对其进行GZip处理。以下操作不起作用:

gz := gzip.NewWriter(myJSON)
因为
[]字节
没有实现
io.Writer


一旦我已经创建了JSON,有什么非常简单的方法可以做到这一点吗?

压缩到缓冲区并发布该缓冲区

 var buf bytes.Buffer
 gz := gzip.NewWriter(&buf)
 gz.Write(myJSON)
 gz.Close()
由于
*bytes.Buffer
统计了
io.Reader
接口,因此您可以在创建请求时直接使用该缓冲区

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

最好的选择是将JSON封送流到gzip编写器:

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()
}
这样做的好处是不会在内存中临时缓冲json,因此速度更快,使用更少的RAM

如果需要将其作为
io.Reader
,例如HTTP请求主体,则可以使用管道进行转换:

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

非常感谢。您是否正在使用“bytesToPost:=buf.Bytes()”执行某些操作?似乎是您创建了它,但在POST中传递&buf时不要使用它。@JimmyD这行代码旨在说明要发布的字节的位置,但似乎没有帮助。请参阅更新的答案。