Goのhttp.RoundTripperについて

アプリケーション

概要

Goのhttp.RoundTripperについてかく。

http.RoundTripperとは

HTTPクライアントの通信を担っているインターフェース。

cf. pkg.go.dev - net/http#RoundTripper

HTTPクライアントにおいてリクエストからレスポンスを受け取るまでの間の処理をカスタマイズすることができる。

HTTPクライアントにおけるミドルウェアというイメージ。

実装例

ソースコードはgithub.comにも置いてある。

RoundTripperインターフェースを実装して、http.Clientに渡すだけでカスタマイズすることができる。

package main

import (
    "fmt"
    "net/http"
    "time"
)

// CustomRoundTripper is a custom implementation of http.RoundTripper
type CustomRoundTripper struct {
    Transport http.RoundTripper
}

func (c *CustomRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) {
    start := time.Now()

    fmt.Printf("Requesting %s %s\n", req.Method, req.URL)

    resp, err := c.Transport.RoundTrip(req)

    elapsed := time.Since(start)
    fmt.Printf("Received response in %v\n", elapsed)

    return resp, err
}

func main() {
    client := &http.Client{
        Transport: &CustomRoundTripper{
            Transport: http.DefaultTransport,
        },
    }

    resp, err := client.Get("https://www.example.com")
    if err != nil {
        fmt.Println("Error:", err)
        return
    }
    defer resp.Body.Close()

    fmt.Println("Status Code:", resp.Status)
}
$ go run main.go
Requesting GET https://www.example.com
Received response in 530.885709ms
Status Code: 200 OK

どこで使う?

HTTPクライアント側でミドルウェア的に何か処理を挟みたいときに使う。

  • ログ出力
  • 認証ヘッダの付与
  • キャッシュ管理
  • APIへのリトライ制御、レートリミッター

などHTTPクライアントで統一的な処理を設定したいときに使えそう。

特定のエンドポイントに対して処理を挟みたいときなどは自前のミドルウェアを用意するほうが柔軟性が高そう。

参考


関連書籍