網頁

2022/7/1

Golang http.Handle與http.HandleFunc區別

Go處理HTTP請求時可利用http.Handlehttp.HandleFunc設定對應的URL pattern和請求處理邏輯,兩者用途相同且內部皆透過DefaultServeMux處理請求,但有以下差別。


差別在於http.Handle(pattern string, handler Handler)的第二個參數為http.Handler
http.HandleFunc(pattern string, handler func(ResponseWriter, *Request))的第二個參數為函式func(ResponseWriter, *Request)

例如下面分別以http.Handlehttp.HandleFunc註冊URL pattern及處理函式f(實務上不能同時設定相同的pattern否則會出現pattern重複註冊的錯誤)。http.Handle的第二個參數必須將函式f轉為http.HandlerFunc(其實作http.Handler)的實例傳入。

main.go

package main

import (
    "net/http"
)

func main() {
    f := func(w http.ResponseWriter, r *http.Request) {
        w.Write([]byte("hello"))
    }
    http.Handle("/hello", http.HandlerFunc(f))
    http.HandleFunc("/hi", f)

    http.ListenAndServe(":8080", nil)
}


觀察原始碼可看到http.Handle直接呼叫DefaultServeMux.Handle並傳入http.Handlerhttp.HandleFunc則呼叫DefaultServeMux.HandleFunc,其第二個參數func(ResponseWriter, *Request)將作為http.HandlerFunc型別(其實作http.Handler介面)的實例,並傳入DefaultServeMux.Handle

http/server.go

...
// 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. // line:2079
type HandlerFunc func(ResponseWriter, *Request)

// ServeHTTP calls f(w, r).
func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) {
    f(w, r)
}

...

// HandleFunc registers the handler function for the given pattern. // line:2510
func (mux *ServeMux) HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {
    if handler == nil {
        panic("http: nil handler")
    }
    mux.Handle(pattern, HandlerFunc(handler))
}

// Handle registers the handler for the given pattern
// in the DefaultServeMux.
// The documentation for ServeMux explains how patterns are matched.
func Handle(pattern string, handler Handler) { DefaultServeMux.Handle(pattern, handler) }

// HandleFunc registers the handler function for the given pattern
// in the DefaultServeMux.
// The documentation for ServeMux explains how patterns are matched.
func HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {
    DefaultServeMux.HandleFunc(pattern, handler)
}



沒有留言:

張貼留言