GoのAPIサーバのレスポンスをgzip圧縮する
今、仕事で作っているGoで作られたAPIサーバは比較的、レスポンスが巨大なものが多く、gzip圧縮した方が良さそうに感じた。
APIサーバはGCP上のAPI gatewayが前段にあり、その後ろでCloud Runで実際の処理が動いている構成。 最初はAPI gatewayとかにgzip圧縮する機能とかありそうとか思ってたが、そういう機能はないみたいなのでAPIサーバ側で実装してみた。
使ったライブラリ
下のリンク先のものを使った。 基本的には1024バイトを超えるレスポンスでないとgzip圧縮しないようになっていたので、小さい大きさのレスポンスの時の圧縮・解凍による性能劣化みたいなことは少ないと思う。
インストール
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 ------------"}%