最簡單的http服務
對於 golang 來說,建立一個http服務是輕而易舉的事情,如下,我們建立了一個非常簡單的http服務,監聽8899埠,只提供一個介面返回hello world
package mainimport ( "fmt" "net/http")func main() { http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "hello world") }) http.ListenAndServe(":8899", nil)}
當你在遊覽器輸入 http://127.0.0.1:8899 時,便能看到 hello world 的輸出
http服務對於 golang 的http服務,我們主要理解兩個物件,:
Handler ,它是請求的處理物件, Handler 物件需要實現 ServeHTTP 方法, ServeHTTP 執行的是我們的業務邏輯,一般我們定義的 func(w http.ResponseWriter, r *http.Request) 的方法需要經過 http.HandlerFunc 包裝為 Handler 物件ServeMux ,它相當於一個路由註冊器,儲存的請求路徑 pattern 和 Handler 物件的map表,透過 pattern 找到對應的 Handler 物件,然後執行 Handler 物件的 ServeHTTP 方法簡單的說,http的執行物件是 handler ,而要成為 handler 物件.則必須實現 ServeHTTP 方法,例如 HandlerFunc 實現了 ServeHTTP 方法,所以它也是一個 handler 物件
handler物件// Handler介面type Handler interface { ServeHTTP(ResponseWriter, *Request)}// HandlerFunc實現了Handler介面type HandlerFunc func(ResponseWriter, *Request)func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) { f(w, r)}
server從路由中找到 handler 物件,執行 handler 物件中的 ServeHTTP 方法,也就是說,要作為路由的 Handler 物件,需要實現 ServeHTTP 方法,有關handler如下:
handler函式,具有 func(w http.ResponseWriter, r *http.Requests) 簽名的函式,需要經過 HandlerFunc 函式包裝,否則不能作為路由的 Handler 物件,handler處理函式,經過 HandlerFunc 結構包裝的handler函式, HandlerFunc 實現了 ServeHTTP 介面方法的函式handler物件,實現了Handler介面 ServeHTTP 方法的結構註冊路由ServeMuxtype ServeMux struct { mu sync.RWMutex m map[string]muxEntry hosts bool }type muxEntry struct { explicit bool h Handler pattern string}// ServeMux也擁有ServeHTTP方法,也就說ServeMux實現了Handler介面,即ServeMuX其實也是一個Handler物件,不過ServeMux的ServeHTTP方法不是用來處理request和respone,而是用來找到路由註冊的handlerfunc (mux *ServeMux) ServeHTTP(w ResponseWriter, r *Request) { if r.RequestURI == "*" { if r.ProtoAtLeast(1, 1) { w.Header().Set("Connection", "close") } w.WriteHeader(StatusBadRequest) return } h, _ := mux.Handler(r) h.ServeHTTP(w, r)}
如上, ServeMux.m 儲存了路由規則 pattern 以及對應的 Handler 處理物件,另外 ServeMux 也擁有 ServeHTTP 方法,也就說 ServeMux 實現了 Handler 介面,即 ServeMuX 其實也是一個 Handler 物件,不過ServeMux的ServeHTTP方法不是用來處理request和respone,而是用來找到路由註冊的handler
package mainimport ( "fmt" "net/http")func main() { mux := http.NewServeMux() mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "hello world") }) mux.HandleFunc("/test", func(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "hello world") }) http.ListenAndServe(":8899", mux)}
Server
http.ListenAndServe(":8899",mux)// 等價於serv := &http.Server{ Addr: ":8899", Handler: mux, }serv.ListenAndServe()
http.ListenAndServe原始碼如下:
func ListenAndServe(addr string, handler Handler) error { server := &Server{Addr: addr, Handler: handler} return server.ListenAndServe()}
來源https://gobea.cn/blog/detail/15zqpwrq.html參考https://www.jianshu.com/p/be3d9cdc680b
最新評論