middleware

package
v1.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 1, 2026 License: MIT Imports: 19 Imported by: 0

Documentation

Overview

Package middleware Echo 프레임워크를 위한 HTTP 미들웨어를 제공합니다.

이 패키지는 API 서버의 공통 기능을 처리하는 다양한 미들웨어를 포함합니다.

제공되는 미들웨어:

  • HTTPLogger: HTTP 요청/응답 로깅 (민감 정보 자동 마스킹)
  • RequireAuthentication: 애플리케이션 키 기반 인증
  • RateLimit: IP 기반 요청 속도 제한
  • PanicRecovery: 패닉 복구 및 에러 로깅
  • DeprecatedEndpoint: 레거시 엔드포인트 경고 헤더 추가
  • LoggerAdapter: Echo 로거를 애플리케이션 로거로 연결

사용 예시:

e := echo.New()
e.Use(middleware.PanicRecovery())
e.Use(middleware.HTTPLogger())
e.Use(middleware.RateLimit(10, 20))

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrAppKeyRequired API 호출 자격 증명인 App Key가 누락되었을 때 반환하는 에러입니다.
	// X-App-Key 헤더 또는 app_key 쿼리 파라미터를 통해 전달되어야 합니다.
	ErrAppKeyRequired = httputil.NewBadRequestError("app_key는 필수입니다 (X-App-Key 헤더 또는 app_key 쿼리 파라미터)")

	// ErrApplicationIDRequired 식별 대상인 Application ID가 요청에 포함되지 않았을 때 반환하는 에러입니다.
	// X-Application-Id 헤더 또는 요청 본문(Body)을 통해 전달되어야 합니다.
	ErrApplicationIDRequired = httputil.NewBadRequestError("application_id는 필수입니다")

	// ErrBodyTooLarge 요청 본문의 크기가 서버 허용 한도(BodyLimit)를 초과했을 때 반환하는 표준 413 에러입니다.
	ErrBodyTooLarge = echo.NewHTTPError(http.StatusRequestEntityTooLarge, "요청 본문이 너무 큽니다")

	// ErrBodyReadFailed 네트워크 문제 등으로 인해 요청 본문을 읽는 데 실패했을 때 반환하는 에러입니다.
	ErrBodyReadFailed = httputil.NewBadRequestError("요청 본문을 읽을 수 없습니다")

	// ErrEmptyBody 필수 요청 본문(Payload)이 비어있어 작업을 수행할 수 없을 때 반환하는 에러입니다.
	ErrEmptyBody = httputil.NewBadRequestError("요청 본문이 비어있습니다")

	// ErrInvalidJSON 요청 본문이 올바른 JSON 형식이 아니어서 파싱에 실패했을 때 반환하는 에러입니다.
	ErrInvalidJSON = httputil.NewBadRequestError("잘못된 JSON 형식입니다")

	// ErrRateLimitExceeded 허용된 요청 빈도를 초과한 클라이언트에게 반환할 표준 HTTP 429(Too Many Requests) 에러입니다.
	ErrRateLimitExceeded = httputil.NewTooManyRequestsError("요청이 너무 많습니다. 잠시 후 다시 시도해주세요")

	// ErrUnsupportedMediaType 클라이언트가 요청한 Content-Type을 서버가 지원하지 않을 때 반환할 표준 HTTP 415(Unsupported Media Type) 에러입니다.
	ErrUnsupportedMediaType = echo.NewHTTPError(http.StatusUnsupportedMediaType, "지원하지 않는 Content-Type 형식입니다")
)

Functions

func DeprecatedEndpoint

func DeprecatedEndpoint(newEndpoint string) echo.MiddlewareFunc

DeprecatedEndpoint Deprecated 엔드포인트에 경고 헤더를 추가하는 미들웨어를 반환합니다.

응답 헤더에 RFC 7234 표준 Warning 헤더와 커스텀 헤더를 추가하여 클라이언트가 deprecated 상태를 인지하고 새 엔드포인트로 마이그레이션할 수 있도록 합니다.

추가되는 헤더:

  • Warning: "299 - \"Deprecated API endpoint. Use {newEndpoint} instead.\""
  • X-API-Deprecated: "true"
  • X-API-Deprecated-Replacement: {newEndpoint}

Parameters:

  • newEndpoint: 대체 엔드포인트 경로 (예: "/api/v1/notifications") 반드시 '/'로 시작하는 비어있지 않은 문자열이어야 함

사용 예시:

v1Group.POST("/notice/message", handler,
    middleware.DeprecatedEndpoint("/api/v1/notifications"))

Panics:

  • newEndpoint가 빈 문자열이거나 '/'로 시작하지 않는 경우

func HTTPLogger

func HTTPLogger() echo.MiddlewareFunc

HTTPLogger HTTP 요청/응답을 구조화된 로그로 기록하는 미들웨어를 반환합니다.

기록되는 정보:

  • 요청: IP, 메서드, URI, User-Agent, Content-Length
  • 응답: 상태 코드, 응답 크기, Request ID
  • 성능: 처리 시간 (마이크로초 및 사람이 읽기 쉬운 형식)
  • 보안: 민감한 쿼리 파라미터 자동 마스킹 (app_key, password 등)

사용 예시:

e := echo.New()
e.Use(middleware.HTTPLogger())

func NewErrPanicRecovered

func NewErrPanicRecovered(r any) error

NewErrPanicRecovered 캡처된 패닉 값을 내부 시스템 오류로 래핑하여 새로운 에러를 생성합니다.

func PanicRecovery

func PanicRecovery() echo.MiddlewareFunc

PanicRecovery 패닉을 복구하고 로깅하는 미들웨어를 반환합니다.

핸들러에서 발생한 패닉을 복구하여 서버 다운을 방지하고, 스택 트레이스와 함께 에러를 로깅한 후 HTTP 500 에러를 반환합니다.

사용 예시:

e := echo.New()
e.Use(middleware.PanicRecovery())

func RateLimit

func RateLimit(requestsPerSecond int, burst int) echo.MiddlewareFunc

RateLimit IP 기반 Rate Limiting 미들웨어를 반환합니다.

Token Bucket 알고리즘을 사용하여 IP별로 요청 속도를 제한합니다. 제한 초과 시 HTTP 429 (Too Many Requests)를 반환하고 Retry-After 헤더를 포함합니다.

Parameters:

  • requestsPerSecond: 초당 허용 요청 수 (양수, 예: 20)
  • burst: 버스트 허용량 (양수, 예: 40)

Token Bucket 알고리즘:

  • Rate: 초당 토큰 생성 속도 (requestsPerSecond)
  • Burst: 버킷 크기 (burst), 최대 저장 가능한 토큰 수
  • 요청마다 토큰 1개 소비, 부족 시 요청 거부

사용 예시:

e := echo.New()
e.Use(middleware.RateLimit(20, 40)) // 초당 20 요청, 버스트 40

주의사항:

  • 메모리 기반 저장소 (서버 재시작 시 초기화)
  • 다중 서버 환경에서는 서버별로 독립적인 제한 적용

Panics:

  • requestsPerSecond 또는 burst가 0 이하인 경우

func RequireAuthentication

func RequireAuthentication(authenticator *auth.Authenticator) echo.MiddlewareFunc

RequireAuthentication 애플리케이션 인증을 수행하는 미들웨어를 반환합니다.

처리 과정:

  1. App Key 추출 (X-App-Key 헤더 우선, app_key 쿼리 파라미터 폴백)
  2. Application ID 추출 (X-Application-Id 헤더 우선, Body 폴백)
  3. Authenticator를 통한 인증 처리
  4. 인증된 Application 객체를 Context에 저장

App Key 추출 우선순위:

  1. X-App-Key 헤더 (권장)
  2. app_key 쿼리 파라미터 (레거시, deprecated)

Application ID 추출 우선순위:

  1. X-Application-Id 헤더 (권장) - HTTP Body는 스트림(Stream)이므로, 미들웨어에서 읽으면 소모되어 사라집니다. - 이를 복구하려면 전체 데이터를 메모리에 복사하고 다시 채워넣는 고비용 작업(I/O + 메모리 할당)이 필요합니다. - 헤더를 사용하면 이러한 "Double Parsing"과 "Stream Restoration" 비용을 "0"으로 만들 수 있습니다.
  2. Request Body (레거시, 호환성 유지) - 헤더가 없는 경우에만 불가피하게 Body를 파싱합니다.

인증 성공 시:

  • Application 객체를 Context에 저장 (auth.SetApplication 사용)
  • 다음 핸들러로 제어 전달

인증 실패 시:

  • 400 Bad Request: App Key/Application ID 누락, 빈 Body, 잘못된 JSON
  • 401 Unauthorized: 미등록 Application ID 또는 잘못된 App Key
  • 413 Request Entity Too Large: 요청 크기가 제한을 초과함 (BodyLimit)

사용 예시:

authMiddleware := middleware.RequireAuthentication(authenticator)
e.POST("/api/v1/notifications", handler, authMiddleware)

Panics:

  • authenticator가 nil인 경우

func ValidateContentType

func ValidateContentType(expectedContentType string) echo.MiddlewareFunc

ValidateContentType 요청의 Content-Type을 검증하는 미들웨어를 반환합니다.

지정된 Content-Type이 요청 헤더에 포함되어 있는지 검사합니다. GET, DELETE 등 본문이 없는 요청이나 본문 길이가 0인 경우에는 검증을 건너뛸 수 있습니다.

Parameters:

  • expectedContentType: 허용할 Content-Type (예: "application/json")

Returns:

  • 415 Unsupported Media Type: Content-Type이 일치하지 않는 경우

Types

type Logger

type Logger struct {
	*applog.Logger
}

Logger Echo의 log.Logger 인터페이스를 구현하는 어댑터입니다.

이 어댑터는 애플리케이션의 로거(applog.Logger)를 Echo 프레임워크의 로거 인터페이스(github.com/labstack/gommon/log.Logger)에 연결합니다.

Echo는 자체 Logger 인터페이스를 요구하므로, 이 어댑터를 통해 애플리케이션 전체에서 일관된 로깅 시스템을 사용할 수 있습니다.

func (Logger) Debug

func (l Logger) Debug(i ...interface{})

func (Logger) Debugf

func (l Logger) Debugf(format string, args ...interface{})

func (Logger) Debugj

func (l Logger) Debugj(j log.JSON)

func (Logger) Error

func (l Logger) Error(i ...interface{})

func (Logger) Errorf

func (l Logger) Errorf(format string, args ...interface{})

func (Logger) Errorj

func (l Logger) Errorj(j log.JSON)

func (Logger) Fatal

func (l Logger) Fatal(i ...interface{})

func (Logger) Fatalf

func (l Logger) Fatalf(format string, args ...interface{})

func (Logger) Fatalj

func (l Logger) Fatalj(j log.JSON)

func (Logger) Info

func (l Logger) Info(i ...interface{})

func (Logger) Infof

func (l Logger) Infof(format string, args ...interface{})

func (Logger) Infoj

func (l Logger) Infoj(j log.JSON)

func (Logger) Level

func (l Logger) Level() log.Lvl

Level 애플리케이션 로그 레벨을 Echo 로그 레벨로 변환합니다.

func (Logger) Output

func (l Logger) Output() io.Writer

Output 현재 출력 Writer를 반환합니다.

func (Logger) Panic

func (l Logger) Panic(i ...interface{})

func (Logger) Panicf

func (l Logger) Panicf(format string, args ...interface{})

func (Logger) Panicj

func (l Logger) Panicj(j log.JSON)

func (Logger) Prefix

func (l Logger) Prefix() string

Prefix Echo의 Prefix 기능은 사용하지 않으므로 빈 문자열을 반환합니다.

func (Logger) Print

func (l Logger) Print(i ...interface{})

func (Logger) Printf

func (l Logger) Printf(format string, args ...interface{})

func (Logger) Printj

func (l Logger) Printj(j log.JSON)

func (Logger) SetHeader

func (l Logger) SetHeader(string)

SetHeader Echo의 Header 기능은 사용하지 않으므로 무시합니다.

func (Logger) SetLevel

func (l Logger) SetLevel(lvl log.Lvl)

SetLevel Echo 로그 레벨을 애플리케이션 로그 레벨로 변환하여 설정합니다.

func (Logger) SetOutput

func (l Logger) SetOutput(w io.Writer)

SetOutput 로그 출력 대상을 설정합니다.

func (Logger) SetPrefix

func (l Logger) SetPrefix(string)

SetPrefix Echo의 Prefix 기능은 사용하지 않으므로 무시합니다.

func (Logger) Warn

func (l Logger) Warn(i ...interface{})

func (Logger) Warnf

func (l Logger) Warnf(format string, args ...interface{})

func (Logger) Warnj

func (l Logger) Warnj(j log.JSON)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL