라우터 수정
라우터에서도 패키지 내에서 정의한 HandlerFunc를 사용하도록 다음과 같이 수정하자.
▼ router.go
package main import ( "net/http" "strings" ) type router struct { // 키: http 메서드 // 값: URL 패턴별로 실행할 HandlerFunc handlers map[string]map[string]HandlerFunc } func (r *router) HandleFunc(method, pattern string, h HandlerFunc) { // http 메서드로 등록된 맵이 있는지 확인 m, ok := r.handlers[method] if !ok { // 등록된 맵이 없으면 새 맵을 생성 m = make(map[string]HandlerFunc) r.handlers[method] = m } // http 메서드로 등록된 맵에 URL 패턴과 핸들러 함수 등록 m[pattern] = h } func (r *router) ServeHTTP(w http.ResponseWriter, req *http.Request) { // http 메서드에 맞는 모든 handers를 반복하면서 요청 URL에 해당하는 handler를 찾음 for pattern, handler := range r.handlers[req.Method] { if ok, params := match(pattern, req.URL.Path); ok { // Context 생성 c := Context{ Params: make(map[string]interface{}), ResponseWriter: w, Request: req, } for k, v := range params { c.Params[k] = v } // 요청 url에 해당하는 handler 수행 handler(&c) return } } // 요청 URL에 해당하는 handler를 찾지 못하면 NotFound 에러 처리 http.NotFound(w, req) return } func match(pattern, path string) (bool, map[string]string) { // ... }
router의 내부 필드인 handlers 타입을 map[string]map[string]HandlerFunc로 변경했다. 라우터의 ServeHTTP() 메서드에서는 요청 URL에 해당하는 핸들러를 수행하기 전에 Context를 생성해서 매개변수로 전달한다. 이때 match() 함수에서 전달된 동적 URL의 매개변수 정보는 Context에 담는다.