Откуда берется утилита 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(),

Другие вопросы по тегам