Menu
Coddy logo textTech

http.Handler 인터페이스

Coddy GO 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨 — 107개 중 77번째.

http.Handler 인터페이스는 Go의 웹 서버 아키텍처의 기초입니다. 이것은 HTTP 요청이 처리되는 방식을 정의하며, 이를 구현하는 모든 타입은 웹 요청을 처리할 수 있습니다.

인터페이스는 놀라울 정도로 단순합니다:

type Handler interface {
    ServeHTTP(ResponseWriter, *Request)
}

ServeHTTP 메서드가 있는 모든 타입은 HTTP 요청을 처리할 수 있습니다. 다음은 커스텀 핸들러의 예입니다:

type GreetHandler struct {
    Greeting string
}

func (h GreetHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "%s, visitor!", h.Greeting)
}

이 핸들러를 서버와 함께 직접 사용할 수 있습니다:

handler := GreetHandler{Greeting: "Welcome"}
http.Handle("/greet", handler)

더 간단한 경우를 위해, Go는 일반 함수를 핸들러로 변환할 수 있게 해주는 타입인 http.HandlerFunc를 제공합니다:

func hello(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "Hello!")
}

http.Handle("/hello", http.HandlerFunc(hello))

이 인터페이스의 강력함은 핸들러가 다른 핸들러를 감쌀 수 있다는 점을 깨달을 때 분명해집니다. 이를 통해 원래의 핸들러 로직을 수정하지 않고도 로깅, 인증 또는 기타 횡단 관심사(cross-cutting concerns)를 추가하는 미들웨어 패턴이 가능해집니다.

challenge icon

챌린지

쉬움

웹 요청이 처리되는 방식을 시뮬레이션하는 간단한 HTTP 핸들러 시스템을 구축해 봅시다! 이 환경에서는 실제 HTTP 서버를 실행할 수 없으므로, http.Handler 인터페이스를 구현하는 핸들러를 만들고 모의(mock) 요청/응답 객체를 사용하여 요청을 처리하는 방법을 시연해 보겠습니다.

코드는 두 개의 파일로 구성됩니다:

  • handlers.go: 사용자 정의 HTTP 핸들러를 정의합니다.

    HTTP 응답에 기록될 내용을 캡처하는 MockResponseWriter 구조체를 만듭니다. 이 구조체는 응답 본문을 문자열로 저장해야 하며, 본문에 데이터를 추가하는 Write(data []byte) (int, error) 메서드를 구현해야 합니다. 누적된 응답을 검색하기 위한 Body() string 메서드도 추가하세요.

    HTTP 요청을 시뮬레이션하기 위해 PathMethod 문자열 필드를 가진 MockRequest 구조체를 만듭니다.

    이제 http.Handler 인터페이스 패턴(*MockResponseWriter*MockRequest를 인자로 받는 ServeHTTP 메서드 포함)을 구현하는 두 개의 핸들러 구조체를 만듭니다:

    • Message 필드를 가진 WelcomeHandler - 메시지 뒤에 요청 경로를 이어서 작성합니다.
    • MethodHandler - 요청 메서드에 따라 다른 응답을 작성합니다: GET의 경우 "Fetching data", POST의 경우 "Creating resource", 그 외의 경우 "Method not supported"를 작성합니다.
  • main.go: 핸들러를 통해 요청을 처리합니다.

    핸들러 유형(welcome 또는 method)을 읽은 다음 요청 세부 정보를 읽습니다. welcome 핸들러의 경우 환영 메시지도 읽습니다.

    적절한 핸들러를 생성하고, 모의 요청을 빌드한 다음 ServeHTTP를 호출하여 처리합니다. 응답 본문을 출력합니다.

다음 입력이 제공됩니다:

  • 1행: 핸들러 유형 (welcome 또는 method)
  • 2행: 요청 경로
  • 3행: 요청 메서드
  • 4행 (welcome인 경우에만): 환영 메시지

예를 들어, 다음과 같이 주어지면:

welcome
/home
GET
Hello from

출력은 다음과 같아야 합니다:

Hello from /home

그리고 다음과 같이 주어지면:

method
/api/users
POST

출력은 다음과 같아야 합니다:

Creating resource

그리고 다음과 같이 주어지면:

method
/api/data
GET

출력은 다음과 같아야 합니다:

Fetching data

그리고 다음과 같이 주어지면:

method
/api/items
DELETE

출력은 다음과 같아야 합니다:

Method not supported

이 챌린지는 http.Handler 인터페이스의 핵심 개념인 ServeHTTP 메서드가 있는 모든 유형이 요청을 처리할 수 있음을 보여줍니다. 실제 애플리케이션에서 http.ResponseWriter*http.Request는 Go의 표준 라이브러리에서 제공되지만, 핸들러를 구현하는 패턴은 완전히 동일합니다.

치트 시트

http.Handler 인터페이스는 Go 웹 서버 아키텍처의 기초입니다:

type Handler interface {
    ServeHTTP(ResponseWriter, *Request)
}

ServeHTTP 메서드를 가진 모든 타입은 HTTP 요청을 처리할 수 있습니다:

type GreetHandler struct {
    Greeting string
}

func (h GreetHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "%s, visitor!", h.Greeting)
}

서버에 핸들러를 등록합니다:

handler := GreetHandler{Greeting: "Welcome"}
http.Handle("/greet", handler)

더 간단한 경우에는 http.HandlerFunc를 사용하여 함수를 핸들러로 변환합니다:

func hello(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "Hello!")
}

http.Handle("/hello", http.HandlerFunc(hello))

핸들러는 다른 핸들러를 감쌀 수 있어 로깅, 인증 또는 기타 공통 관심 사항을 위한 미들웨어 패턴을 가능하게 합니다.

직접 해보기

package main

import (
	"bufio"
	"fmt"
	"os"
)

func main() {
	scanner := bufio.NewScanner(os.Stdin)
	
	// 핸들러 타입 읽기
	scanner.Scan()
	handlerType := scanner.Text()
	
	// 요청 경로 읽기
	scanner.Scan()
	path := scanner.Text()
	
	// 요청 메서드 읽기
	scanner.Scan()
	method := scanner.Text()
	
	// 모의(mock) 요청 생성
	request := &MockRequest{
		Path:   path,
		Method: method,
	}
	
	// 모의(mock) 응답 작성기 생성
	response := &MockResponseWriter{}
	
	// TODO: handlerType에 따라 적절한 핸들러를 생성하십시오.
	// handlerType이 "welcome"인 경우, 환영 메시지를 읽고 WelcomeHandler를 생성합니다.
	// handlerType이 "method"인 경우, MethodHandler를 생성합니다.
	// 응답과 요청을 사용하여 핸들러의 ServeHTTP를 호출합니다.
	
	if handlerType == "welcome" {
		scanner.Scan()
		message := scanner.Text()
		// TODO: 메시지를 사용하여 WelcomeHandler를 생성하고 ServeHTTP를 호출합니다.
		_ = message // 구현 시 이 라인을 제거하십시오.
	} else if handlerType == "method" {
		// TODO: MethodHandler를 생성하고 ServeHTTP를 호출합니다.
	}
	
	// 응답 본문 출력
	fmt.Println(response.Body())
}
quiz icon실력 점검

이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.

객체 지향 프로그래밍의 모든 레슨