Откуда берется утилита serveHTTP на якобы голой функции? - PullRequest
0 голосов
/ 02 декабря 2018

У меня есть эта утилита:

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(w http.ResponseWriter, r *http.Request) { ... }

так как же эта функцияесть ли у него ServeHTTP функция?

Другими словами, почему я звоню

h.ServeHTTP(w,r)

вместо

h(w,r)

?

1 Ответ

0 голосов
/ 02 декабря 2018

http.HandlerFunc представляет собой тип, представляющий func(ResponseWriter, *Request).

Разница между http.HandlerFunc и func(ResponseWriter, *Request) состоит в следующем: * тип 1008 * имеет метод, называемый 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() method.


Существует также другой тип, интерфейс с именем 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().

...