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

GO · 패턴

미들웨어 패턴 (HTTP)

범용 HTTP 미들웨어 패턴. 요청 ID, 타임아웃, 인증을 미들웨어로 분리합니다.

패턴고급middlewarerequest-idtimeoutauth

핵심 설명

범용 HTTP 미들웨어 패턴. 요청 ID, 타임아웃, 인증을 미들웨어로 분리합니다.

Go code

package main

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

	"crypto/rand"
	"encoding/hex"
)

type ctxKey string

func RequestID(next http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		id := r.Header.Get("X-Request-ID")
		if id == "" {
			b := make([]byte, 8)
			rand.Read(b)
			id = hex.EncodeToString(b)
		}
		ctx := context.WithValue(r.Context(), ctxKey("requestID"), id)
		w.Header().Set("X-Request-ID", id)
		next.ServeHTTP(w, r.WithContext(ctx))
	})
}

func Timeout(d time.Duration) func(http.Handler) http.Handler {
	return func(next http.Handler) http.Handler {
		return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
			ctx, cancel := context.WithTimeout(r.Context(), d)
			defer cancel()
			next.ServeHTTP(w, r.WithContext(ctx))
		})
	}
}

func RequireAuth(next http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		token := r.Header.Get("Authorization")
		if token == "" {
			http.Error(w, "인증 필요", 401)
			return
		}
		next.ServeHTTP(w, r)
	})
}

func main() {
	handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		reqID := r.Context().Value(ctxKey("requestID"))
		fmt.Fprintf(w, "요청 ID: %s\n", reqID)
	})

	wrapped := RequestID(Timeout(5*time.Second)(RequireAuth(handler)))
	fmt.Println("미들웨어 스택 준비:", wrapped)
}

학습 팁

요청 ID 미들웨어는 로그 추적에 필수입니다. 모든 로그에 요청 ID를 포함하면 분산 시스템에서 요청 흐름을 추적할 수 있습니다.

주의할 점

미들웨어에서 설정한 context 값을 다운스트림에서 사용하려면 r.WithContext(ctx)로 새 요청을 만들어야 합니다.

자주 묻는 질문

미들웨어 패턴 (HTTP)란 무엇인가요?

범용 HTTP 미들웨어 패턴. 요청 ID, 타임아웃, 인증을 미들웨어로 분리합니다.

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

미들웨어에서 설정한 context 값을 다운스트림에서 사용하려면 r.WithContext(ctx) 로 새 요청을 만들어야 합니다.