Откуда берется утилита serveHTTP на якобы голой функции?
У меня есть эта утилита:
type Handler struct{}
func (h Handler) Mount(router *mux.Router, v PeopleInjection) {
router.HandleFunc("/api/v1/people", h.makeGetMany(v)).Methods("GET")
}
вышесказанное называет это:
func (h Handler) makeGetMany(v PeopleInjection) http.HandlerFunc {
type RespBody struct {}
type ReqBody struct {
Handle string
}
return tc.ExtractType(
tc.TypeList{ReqBody{},RespBody{}},
func(w http.ResponseWriter, r *http.Request) {
// ...
})
}
а потом tc.ExtractType
это так:
func ExtractType(s TypeList, h http.HandlerFunc) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
h.ServeHTTP(w, r) // <<< h is just a func right? so where does ServeHTTP come from?
}
}
Мой вопрос - откуда берется метод / функция serveHTTP??
это не h
Параметр просто func с этой подписью:
func(w http.ResponseWriter, r *http.Request) { ... }
так как же этот функционал имеет ServeHTTP
к нему привязаны?
Другими словами, почему я звоню
h.ServeHTTP(w,r)
вместо
h(w,r)
?
1 ответ
Http.HandlerFunc - это тип, представляющий func(ResponseWriter, *Request)
,
Разница между http.HandlerFunc
а также func(ResponseWriter, *Request)
является: http.HandlerFunc
тип имеет метод с именем ServeHTTP()
,
Из исходного кода:
// The HandlerFunc type is an adapter to allow the use of
// ordinary functions as HTTP handlers. If f is a function
// with the appropriate signature, HandlerFunc(f) is a
// Handler that calls f.
type HandlerFunc func(ResponseWriter, *Request)
// ServeHTTP calls f(w, r).
func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) {
f(w, r)
}
http.HandlerFunc()
может использоваться для переноса функции обработчика
func Something(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// do something
next.ServeHTTP(w, r)
})
}
Завёрнутый обработчик будет иметь http.HandlerFunc()
типа, то есть мы сможем получить доступ к нему .ServeHTTP()
метод.
Существует также другой тип, интерфейс под названием http.Handler. Она имеет .ServeHTTP()
подпись метода, и она должна быть реализована в структуре, в которую встроен интерфейс.
type Handler interface {
ServeHTTP(ResponseWriter, *Request)
}
Как вы можете видеть на Something()
функция выше, возвращаемое значение в http.Handler
тип обязателен, но мы вернули обработчик http.HandlerFunc()
, Это нормально, потому что http.HandlerFunc
имеет метод .ServeHTTP()
кто выполняет требование http.Handler
интерфейс.
Другими словами, почему я звоню
h.ServeHTTP(w,r)
вместоh(w,r)
?
Потому что для продолжения обслуживания входящего запроса необходимо позвонить .ServeHTTP()
,