miyazi888の覚え書き日記

学習したことを書き留めてます。

GoのAPIサーバのレスポンスをgzip圧縮する

今、仕事で作っているGoで作られたAPIサーバは比較的、レスポンスが巨大なものが多く、gzip圧縮した方が良さそうに感じた。

APIサーバはGCP上のAPI gatewayが前段にあり、その後ろでCloud Runで実際の処理が動いている構成。 最初はAPI gatewayとかにgzip圧縮する機能とかありそうとか思ってたが、そういう機能はないみたいなのでAPIサーバ側で実装してみた。

使ったライブラリ

下のリンク先のものを使った。 基本的には1024バイトを超えるレスポンスでないとgzip圧縮しないようになっていたので、小さい大きさのレスポンスの時の圧縮・解凍による性能劣化みたいなことは少ないと思う。

github.com

インストール

go get github.com/klauspost/compress

組み込み例

package main

import (
    "log"
    "net/http"

    "github.com/klauspost/compress/gzhttp"
)

func main() {
    mux := http.NewServeMux()
    mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        w.Header().Set("Content-Type", "application/json")
        w.Write([]byte("{\"test\": \"--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------\"}"))
    })

    handler := gzhttp.GzipHandler(handler)

    log.Fatal(http.ListenAndServe(":8080", handler))
}

動作確認

curlで以下のようにして確認。 --compressedオプションを付けることでAccept-Encoding: gzipみたいな感じなる模様。

リクエス

curl -v --compressed http://localhost:8080/

レスポンス

レスポンスヘッダーにContent-Encoding: gzipが意図どおりに付いているので、gzip圧縮されていることがわかる。

*   Trying 127.0.0.1:8080...
* Connected to localhost (127.0.0.1) port 8080 (#0)
> GET / HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.86.0
> Accept: */*
> Accept-Encoding: deflate, gzip, br, zstd
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Content-Encoding: gzip
< Content-Type: application/json
< Vary: Accept-Encoding
< Date: Sun, 10 Dec 2023 11:15:36 GMT
< Content-Length: 48
<
{"test": "----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------* Connection #0 to host localhost left intact
------------"}%