🙆
Go - EchoのContextを利用してデータを伝搬させる
contextは何か
Go標準のコンテキスト context.Context
下記でまとめて頂いている内容に勝る結論はありません。。。
読み進めていくのが難しいと感じる方もいるかもしれません。
簡単に表現します。
リクエストのキャンセル・タイムアウト・値の伝搬などに使用される。
処理が1つのメソッドで終了することは無いと思います。処理が伝搬していく際に、後続の処理をキャンセルしたり、後続の処理に値を渡していくことが簡単にできるパッケージです。
Echoのコンテキスト echo.Context
Echo フレームワークがリクエストごとに作成し、HTTPリクエストの情報などを保持する。Golangのcontext機能も利用できる。
Echoのコンテキスト echo.Context でログを見る
echo.Contextはハンドラー関数で取得します。ハンドラー関数はecho.HandlerFunc型の関数です。
middlewareの関数・Controllerの関数として実装します。
echo.Contextからhttpリクエストを取得する例
middlewareを利用して、httpリクエストの内容を取得する処理を作ります。
ハンドラー関数は引数に echo.Context を持ちます。
package middleware
import (
"fmt"
"github.com/labstack/echo/v4"
)
// リクエストの情報を出力
func PrintRequestMiddleware(next echo.HandlerFunc) echo.HandlerFunc {
return func(c echo.Context) error {
req := c.Request()
// HTTP メソッド, URI, クエリパラメータ, ヘッダーをログに記録
fmt.Printf("[Middleware] %s %s?%s\n", req.Method, req.RequestURI, req.URL.RawQuery)
fmt.Printf("[Middleware] Headers: %v\n", req.Header)
return next(c) // 次のハンドラーを実行
}
}
echoに反映
e := echo.New()
e.Use(middleware.PrintRequestMiddleware)
middleware -> controllerへecho.Contextの受け渡し
golangでも、echoでも、contextは、伝搬させる際に有効な手段となります。
echoにおいて、middleware -> controllerにecho.Contextを受け渡す実験をします。
middleware
package middleware
import (
"fmt"
"github.com/labstack/echo/v4"
)
// contextに情報を入力
func SetRequestMiddleware(next echo.HandlerFunc) echo.HandlerFunc {
return func(c echo.Context) error {
c.Set("custom_value", "Hello from Middleware")
return next(c) // 次のハンドラーを実行
}
}
Controller
package controller
import (
"fmt"
"net/http"
"github.com/labstack/echo/v4"
)
// GetCustomValue は `echo.Context` からデータを取得してレスポンスを返す
func GetCustomValue() echo.HandlerFunc {
return func(c echo.Context) error {
// `echo.Context` から値を取得
value := c.Get("custom_value")
// ログに出力
fmt.Printf("[Controller] Retrieved custom_value: %v\n", value)
// JSON レスポンスを返す
return c.JSON(http.StatusOK)
}
}
echo起動
package main
import (
"github.com/labstack/echo/v4"
"your_project/controller"
"your_project/middleware"
)
func main() {
e := echo.New()
// ミドルウェアを適用
e.Use(middleware.SetCustomValueMiddleware)
// ルートの登録
e.GET("/custom", controller.GetCustomValue())
// サーバーを起動
e.Logger.Fatal(e.Start(":8080"))
}
[Controller] Retrieved custom_value: Hello from Middleware
こちらが出力されます。
Contextを利用することで、レイヤーを超えてデータを伝搬させることが出来ました。
Discussion