2024-02-21
概要
- echo は Go のウェブフレームワーク
- echo の Middleware でレスポンスボディを加工する方法を検討した
c.Set()
を使う方法を紹介する- 他に
Context
自体をカスタマイズする方法やc.Response().Writer
を使う方法がある
レスポンスボディを加工したい
echo で次のようなコードを記述した。
Middleware でレスポンスボディ (ApiResponse) を加工したい。
package main import ( "github.com/labstack/echo/v4" ) type ApiResponse struct { Data interface{} `json:"data"` } func main() { app := echo.New() // ミドルウェアでレスポンスボディを加工したい // app.Use(SomethingMiddleware) // ハンドラー app.GET("/api/hello", func(c echo.Context) error { // このレスポンスをミドルウェアで加工したい res := ApiResponse { Data: struct{}{}, } return c.JSON(200, res) }) app.Start(":3000") }
だがレスポンスボディを気軽にぱっと get
/ set
する方法が無さそう。
c.Response().Writer
を使う方法は見つけたが、手がかかりそうな印象。
そのため別の方法を検討した。
c.Set() でデータをセットする
c.Set()
でデータをセットして c.Get()
でデータを取得できる
// データをセット c.Set("data", data)
この c.Set()
を使えばミドルウェアへデータを渡せそう。
これを活用して最終的に次のように実装した。
最終的なコード
変更内容
- Handler で
c.JSON()
を呼ばない - 代わりに
c.Set()
でデータをセットする - Middleware でデータを取り出し加工、、最後に c.JSON() でレスポンスを返す
package main import ( "github.com/labstack/echo/v4" ) type ApiResponse struct { Data interface{} `json:"data"` } // データをセット func WithData(c echo.Context, data interface{}) error { c.Set("data", data) return nil } // ミドルウェア func HandleData(next echo.HandlerFunc) echo.HandlerFunc { return func(c echo.Context) error { // ハンドラーを実行 err := next(c) if err != nil { return err } // データを取り出す data := c.Get("data") if data == nil { data = struct{}{} } // レスポンスを返す res := ApiResponse { Data: data, } return c.JSON(200, res) } } func main() { app := echo.New() // ミドルウェア app.Use(HandleData) // ハンドラー app.GET("/api/hello", func(c echo.Context) error { return WithData(c, struct{}{}) }) app.Start(":3000") }
終わりに
API全体で共通のフィールドがあるとき、上記の機構が便利かもです。
作成日
2024-02-21
更新日
2024-02-21