Полезная нагрузка GZip JSON в GoLang до POST - PullRequest
0 голосов
/ 11 июля 2019

У меня есть объект JSON типа []byte, который я создал из структуры, используя json.Marshal. Я хочу сжать JSON перед публикацией на моей конечной точке. Следующее не работает:

gz := gzip.NewWriter(myJSON)

потому что []byte не реализует io.Writer.

Есть ли какой-нибудь очень простой способ сделать это, когда я уже создал свой JSON?

Ответы [ 2 ]

4 голосов
/ 11 июля 2019

Сжать в буфер и опубликовать этот буфер.

 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")
1 голос
/ 11 июля 2019

Лучшим вариантом является потоковая передача маршалинга 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 в памяти, поэтому он будет быстрее и будет использовать меньше оперативной памяти.

Если вам нужно это как 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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...