http.Handler 인터페이스
Coddy GO 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨. 107개 중 77번째.
http.Handler interface는 Go 웹 서버 아키텍처의 기반입니다. HTTP 요청이 처리되는 방식을 정의하며, 이를 implementing하는 모든 타입은 웹 요청을 처리할 수 있습니다.
인터페이스는 놀라울 정도로 간단합니다:
type Handler interface {
ServeHTTP(ResponseWriter, *Request)
}ServeHTTP method를 가진 모든 타입은 HTTP 요청을 처리할 수 있습니다. 다음은 사용자 지정 handler입니다:
type GreetHandler struct {
Greeting string
}
func (h GreetHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "%s, visitor!", h.Greeting)
}이 handler를 서버와 함께 직접 사용할 수 있습니다:
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))이 인터페이스의 강력함은 handler가 다른 handler를 감쌀 수 있다는 점을 깨달으면 분명해집니다. 이를 통해 원래 handler의 로직을 수정하지 않고도 로깅, 인증 또는 기타 횡단 관심사를 추가하는 미들웨어 패턴을 사용할 수 있습니다.
챌린지
쉬움웹 요청이 처리되는 방식을 시뮬레이션하는 간단한 HTTP handler 시스템을 만들어 봅시다! 이 환경에서는 실제 HTTP 서버를 실행할 수 없으므로, http.Handler interface를 implement하는 handler를 만들고 mock request/response 객체를 사용하여 요청을 처리하는 방식을 보여 줍니다.
코드를 두 개의 파일로 구성합니다:
handlers.go: 사용자 지정 HTTP handler를 정의합니다.HTTP response에 기록될 내용을 captures하는
MockResponseWriterstruct를 만듭니다. response body를 string으로 저장하고, data를 body에 appends하는Write(data []byte) (int, error)method를 implement해야 합니다. 누적된 response를 가져올 수 있도록Body() stringmethod를 추가합니다.HTTP request를 시뮬레이션하기 위해
Path및Methodstring field를 포함하는MockRequeststruct를 만듭니다.이제
http.Handlerinterface pattern을 implement하는 두 개의 handler struct를 만듭니다 (*MockResponseWriter및*MockRequest를 인수로 받는ServeHTTPmethod 포함):WelcomeHandler는Messagefield를 가지며, message 뒤에 request path를 기록합니다.MethodHandler는 request method에 based하여 different response를 기록합니다: GET에는"Fetching data", POST에는"Creating resource", 그 외 anything에는"Method not supported"를 사용합니다.
main.go: handler를 통해 request를 처리합니다.handler type(
welcome또는method)을 읽은 다음 request 세부 정보를 읽습니다. welcome handler의 경우 welcome message도 읽습니다.appropriate handler를 만들고, mock request를 구성한 다음
ServeHTTP를 call하여 처리합니다. response body를 출력합니다.
다음 input이 제공됩니다:
- Line 1: Handler type (
welcome또는method) - Line 2: Request path
- Line 3: Request method
- Line 4 (welcome인 경우에만): Welcome message
예를 들어, 다음이 주어졌다고 합시다:
welcome
/home
GET
Hello fromoutput은 다음과 같아야 합니다:
Hello from /home또한 다음이 주어졌다고 합시다:
method
/api/users
POSToutput은 다음과 같아야 합니다:
Creating resource또한 다음이 주어졌다고 합시다:
method
/api/data
GEToutput은 다음과 같아야 합니다:
Fetching data또한 다음이 주어졌다고 합시다:
method
/api/items
DELETEoutput은 다음과 같아야 합니다:
Method not supported이 challenge는 http.Handler interface의 핵심 개념을 보여 줍니다. ServeHTTP method를 가진 모든 type은 request를 처리할 수 있습니다. 실제 application에서는 http.ResponseWriter와 *http.Request가 Go standard library에서 제공되지만, handler를 implement하는 pattern은 정확히 동일하게 유지됩니다.
직접 해보기
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 응답 writer 생성
response := &MockResponseWriter{}
// TODO: handlerType에 따라 적절한 핸들러 생성
// handlerType이 "welcome"이면 welcome 메시지를 읽고 WelcomeHandler 생성
// handlerType이 "method"이면 MethodHandler 생성
// 핸들러에서 response와 request로 ServeHTTP 호출
if handlerType == "welcome" {
scanner.Scan()
message := scanner.Text()
// TODO: message로 WelcomeHandler를 생성하고 ServeHTTP 호출
_ = message // 구현 시 이 줄 제거
} else if handlerType == "method" {
// TODO: MethodHandler를 생성하고 ServeHTTP 호출
}
// 응답 본문을 출력합니다
fmt.Println(response.Body())
}
이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.
객체 지향 프로그래밍의 모든 레슨
8에러 처리와 OOP
error 인터페이스사용자 정의 에러 타입에러 래핑 (fmt.Errorf)센티넬 에러errors.Is()와 errors.As()Panic, Defer, Recover요약 - 파일 파서11표준 라이브러리 & OOP
io.Reader & io.Writersort.Interfacefmt.Stringer 인터페이스encoding/json과 구조체http.Handler 인터페이스요약 - REST API 모델직접 연습해 보세요: 온라인 Go 컴파일러