我们有一个接受JSON的API。我们鼓励人们在发布有效负载之前先对其进行gzip压缩,因为我们对大小施加了限制。我想查看原始JSON和gzip的大小之间的实际差异,但在构建http请求后,似乎无法可靠,准确地获取它。
对于非压缩版本,MyJSON []byte
是原始数据,然后我将其填充到http请求中,如下所示:
req, err := http.NewRequest("POST", url, bytes.NewBuffer(MyJSON))
对于gzip版本,我将数据压缩到缓冲区中,然后将其添加到http请求中,如下所示:
req, err := http.NewRequest("POST", url, &buffer)
是否可以获取http请求的大小?如果没有,我应该可以使用MyJSON []byte
来获得原始len()
的大小,但是对于压缩版本,我似乎无法得到bytes.Buffer
的大小。 / p>
答案 0 :(得分:1)
总之:不。
这是因为http.Request
对象的主体是io.Reader
,它可以有任意大小,而知道io.Reader
大小的唯一方法是全部读取它,并且计数。在实践中,io.Reader
甚至在数据已经传输之后才被消耗。
这对您的应用程序意味着两个选择:
后者会更有效,但是这意味着您无法在发送请求之前主动处理数据。如果选择第二种方法,则可以编写一个自定义io.Reader
来计数读取的字节,并将其传递给NewRequest()
调用。
还请注意:JSON放在字节片([]byte
)中的事实有点代码味道。在某些情况下这可能是适当的,但是在大多数情况下,将JSON直接流式传输到HTTP请求会更有效(就内存和时间而言)。示例:
var someBigHairyObject = /* Perhaps a struct or map */
r, w := io.Pipe()
go func() {
err := json.NewEncoder(w).Encode(someBigHairyObject)
w.CloseWithError(err)
}()
req, _ := http.NewRequest("POST", "http://example.com/", r)
通过这种方式,JSON封送(您也可以在此处包括gzip)直接“完成”到网络,而无需使用内存的中间缓冲区,从而推迟了您的请求。
答案 1 :(得分:0)