💌
GoでのMiddlewareの役割と実装方法についてまとめ
はじめに
Middlewareは、HTTPリクエストとレスポンスの処理をフック(hook)し、共通の処理を適用するための仕組みのことです。
Goでは、主にnet/http
パッケージを使用して簡単にMiddlewareを実装することができます。
今回はMiddlewareの基本概念、Goにおける実装方法と活用例を簡単にまとめました。
対象読者
- GoのMiddlewareの基本を学びたい方
- 共通の処理を効率的に適用する方法を知りたい方
- 実践的なMiddlewareの書き方を学びたい方
目次
- Middlewarrとは?
- Middlewareの役割
- Middlewareを使うメリット
- GoでのMiddlewareの基本
- Goの
net/http
を使ったMiddleware - シンプルなMiddlewareの実装
- Goの
- 実践的なMiddlewareの例
- ロギングMiddleware
- 認証Middleware
- CORS Middleware
- まとめ
1. Middlewareとは?
1.1 Middlewareの役割
Middlewareは、HTTPリクエストを処理する前後で特定の処理を実行する仕組みです。
例えば、以下のような処理をMiddlewareで実装できます。
役割 | 説明 |
---|---|
ロギング | リクエストの情報を記録する |
認証 | ユーザーの認証を行う |
CORS対応 | クロスオリジンリクエストを許可する |
リクエストバリデーション | リクエストデータの検証を行う |
1.2 Middlewareを使うメリット
Middlewareを導入することで、以下のような開発効率の向上が期待できます。
- 共通処理を一箇所にまとめられる → コードの重複を削減
- リクエストの前処理・後処理が簡単にできる
- 複数のMiddlewareを組み合わせて柔軟な制御が可能
2. GoでのMiddlewareの基本
net/http
を使ったMiddleware
2.1 GoのGoでは、http.Handler
をラップする関数を使ってMiddlewareを実装できます。
Middlewareの基本構造
package main
import (
"fmt"
"net/http"
)
// Middlewareの定義
func middleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Println("Middleware: リクエストを処理中...")
next.ServeHTTP(w, r)
fmt.Println("Middleware: レスポンスを返しました。")
})
}
func handler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "Hello, World!")
}
func main() {
http.Handle("/", middleware(http.HandlerFunc(handler)))
http.ListenAndServe(":8080", nil)
}
2.2 シンプルなMiddlewareの実装
このMiddlewareは、リクエストが処理される前後にメッセージを出力します。
-
middleware()
はhttp.Handler
を受け取り、新しいhttp.Handler
を返す -
next.ServeHTTP(w, r)
を実行することで、次の処理(エンドポイントのハンドラー)を呼び出す
実行すると、リクエストごとにリクエストの前後でログが表示されます。
3. 実践的なMiddlewareの例
3.1 ロギングMiddleware
リクエストの URL・メソッド・処理時間を記録するMiddleware。
package main
import (
"log"
"net/http"
"time"
)
func loggingMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
start := time.Now()
next.ServeHTTP(w, r)
duration := time.Since(start)
log.Printf("%s %s %v", r.Method, r.URL.Path, duration)
})
}
3.2 認証Middleware(JWT)
JWT(JSON Web Token)を使った認証 Middlewareの例。
package main
import (
"net/http"
)
func authMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
token := r.Header.Get("Authorization")
if token != "valid-token" {
http.Error(w, "Unauthorized", http.StatusUnauthorized)
return
}
next.ServeHTTP(w, r)
})
}
-
Authorization
ヘッダーに"valid-token"
が含まれている場合のみ許可 - 不正なリクエストは
401 Unauthorized
を返す
3.3 CORS Middleware
フロントエンド(ReactやVueなど)と連携する際に、CORSを許可する Middleware。
package main
import "net/http"
func corsMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Access-Control-Allow-Origin", "*")
w.Header().Set("Access-Control-Allow-Methods", "GET, POST, OPTIONS")
w.Header().Set("Access-Control-Allow-Headers", "Content-Type")
if r.Method == "OPTIONS" {
w.WriteHeader(http.StatusOK)
return
}
next.ServeHTTP(w, r)
})
}
- すべてのオリジン(
*
)を許可 -
OPTIONS
リクエストに200 OK
を返すことで、プリフライトリクエストを処理
4. まとめ
項目 | 説明 |
---|---|
Middlewareの役割 | 共通処理(ロギング、認証、CORSなど)を適用する |
GoでのMiddlewareの書き方 |
http.Handler をラップする関数を作成 |
実践的なMiddleware | ロギング・認証・CORSなどの Middlewareを実装 |
Middlewareを組み合わせてAPIの拡張性を向上させることもできたりします。
フロントエンドと連携するようなWebアプリケーションを作成するときには恐らく触れる概念だと思うので、是非検証してみてください!
Discussion