PHpullh
학습 라이브러리/Go/미들웨어 체이닝 (HTTP)

GO · 파일/IO

미들웨어 체이닝 (HTTP)

HTTP 미들웨어를 체이닝하여 로깅, CORS, 인증 등 횡단 관심사를 분리합니다.

파일/IO고급middlewarechaincorsrecoverylogging

핵심 설명

HTTP 미들웨어를 체이닝하여 로깅, CORS, 인증 등 횡단 관심사를 분리합니다.

Go code

package main

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

type Middleware func(http.Handler) http.Handler

func Chain(h http.Handler, mws ...Middleware) http.Handler {
	for i := len(mws) - 1; i >= 0; i-- {
		h = mws[i](h)
	}
	return h
}

func Logger(next http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		start := time.Now()
		next.ServeHTTP(w, r)
		slog.Info("요청", "method", r.Method,
			"path", r.URL.Path, "duration", time.Since(start))
	})
}

func CORS(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,PUT,DELETE")
		if r.Method == "OPTIONS" {
			w.WriteHeader(204)
			return
		}
		next.ServeHTTP(w, r)
	})
}

func Recovery(next http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		defer func() {
			if err := recover(); err != nil {
				slog.Error("패닉 복구", "error", err)
				http.Error(w, "Internal Server Error", 500)
			}
		}()
		next.ServeHTTP(w, r)
	})
}

func main() {
	mux := http.NewServeMux()
	mux.HandleFunc("GET /", func(w http.ResponseWriter, r *http.Request) {
		fmt.Fprintln(w, "Hello!")
	})

	handler := Chain(mux, Recovery, Logger, CORS)
	fmt.Println("미들웨어 체인: Recovery → Logger → CORS → Handler")
	_ = handler // http.ListenAndServe(":8080", handler)
}

학습 팁

미들웨어 순서가 중요합니다. Recovery는 가장 바깥에, Logger는 그 다음에 배치하여 모든 패닉과 요청을 캡처하세요.

주의할 점

미들웨어에서 next.ServeHTTP를 호출하지 않으면 체인이 중단됩니다. 의도적 중단(인증 실패)이 아니면 반드시 호출하세요.

자주 묻는 질문

미들웨어 체이닝 (HTTP)란 무엇인가요?

HTTP 미들웨어를 체이닝하여 로깅, CORS, 인증 등 횡단 관심사를 분리합니다.

미들웨어 체이닝 (HTTP) 학습 시 주의할 점은 무엇인가요?

미들웨어에서 next.ServeHTTP 를 호출하지 않으면 체인이 중단됩니다. 의도적 중단(인증 실패)이 아니면 반드시 호출하세요.