В пакете http ListenAndServe имеет следующую подпись
func ListenAndServe(addr string, handler Handler) error
, где Handler
(т.е. http.Handler
) - это интерфейс
type Handler interface {
ServeHTTP(ResponseWriter, *Request)
}
Для одного веб-приложения существует только один вызов ListenAndServe
, то есть только один handler
, который должен работать со всеми точками доступа, такими как /url1
, /url2
и т. Д. Если мы напишем handler
с нуля, реализация может быть пользовательской struct
, которая обхватывает дескриптор базы данных.Его метод ServeHTTP
проверяет точку доступа и записывает соответствующий контент в ResponseWriter
, что довольно утомительно и смешанно.
Это мотивация ServeMux , то есть router
в вашем коде.Он имеет метод ServeHTTP , поэтому он удовлетворяет интерфейсу http.Handler
и может использоваться для ListenAndServe
.Кроме того, он имеет метод HandleFunc
для работы с отдельной точкой доступа
func (mux *ServeMux) HandleFunc(pattern string,
handler func(ResponseWriter, *Request))
Обратите внимание, что handler
не является http.Handler
, т. Е. У него нет метода ServeHTTP
,В этом нет необходимости, поскольку mux
уже имеет ServeHTTP
, а его метод ServeHTTP
может отправлять запрос отдельной точки доступа соответствующим обработчикам.
Обратите внимание, что у него также есть метод Handle
, который требует, чтобы аргумент удовлетворял интерфейсу http.Handler
.Это немного менее удобно по сравнению с методом HandleFunc
.
func (mux *ServeMux) Handle(pattern string, handler Handler)
Теперь вернемся к вашему вопросу, поскольку вы вызываете router.HandleFunc
, его ввод не обязательно должен быть http.Handler
.Поэтому альтернативным решением является использование func(ResponseWriter, *Request)
в качестве типа возврата для промежуточного программного обеспечения и makeGetMany
метода.(утверждение типа в промежуточном программном обеспечении также должно быть обновлено, возможно, нужно обновить гораздо больше кода)
@ xpare решение состоит в том, чтобы выполнить преобразование типа так, чтобы все сигнатуры функций совпадали, т.е.конвертировать func(ResponseWriter, *Request)
в http.HandlerFunc
.Также интересно посмотреть, как это работает.Из реализации
// 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)
}
вы можете видеть, что он в основном определяет метод ServeHTTP
для вызова самого себя.