net/http 包涵蓋了與 HTTP 請求發送和處理的相關代碼。雖然包中定義了大量類型、函數,但最重要、最基礎的概念只有兩個:ServeMux 和 Handler。
ServeMux 是 HTTP 請求多路復用器(即路由器,HTTP request router),記錄着請求路由表。對於每一個到來的請求,它都會比較請求路徑和路由表中定義的 URL 路徑,並調用指定的 handler 來處理請求。
Handler 的任務是返回一個 response 消息,並把 header 和 body 寫入消息中。任何對象只要實現了 http.Handler 接口的接口方法 ServeHTTP 就可以成為 handler。ServeHTTP 的方法簽名是:ServeHTTP(ResponseWriter, *Request)。
我們先通過以下代碼,快速了解它們的功能:
package main
import (
"io"
"log"
"net/http"
)
type myHandler struct{}
func (h *myHandler) ServeHTTP(w http.ResponseWriter, _ *http.Request) {
io.WriteString(w, "Hello world!\n")
}
func main() {
mux := http.NewServeMux()
h := new(myHandler)
mux.Handle("/foo", h)
log.Println("Listening...")
http.ListenAndServe(":3000", mux)
}
代碼拆解如下:
- 首先,使用 http.NewServeMux 方法生成一個 HTTP 請求路由器。該方法內部邏輯其實是 return new(ServeMux);
- 然后我們創建了一個自定義 handler,功能是返回 Hello world! 文本;
- 接着,通過 mux.Handle 函數,將該 handler 注冊到新創建的 ServeMux 對象中。這樣 handler 就可以和 URL 路徑 /foo 關聯了;
- 最后,我們創建一個 server 並在 3000 端口監聽請求。這里 ListenAndServe 的方法簽名是 ListenAndServe(addr string, handler Handler),我們之所以可以 ServeMux 作為第二個參數,是因為 ServeMux 實現了 ServeHTTP 接口方法。
掌握了這兩個概念,基本上其他概念 比如 Server,Client 類型、HandleFunc 函數作為 handler 等, 就都很好理解了。另外, 如果你對包中 HTTP 相關的概念不是很清楚的話,比如 TCP keep-alive、proxy、redirect、cookie、TLS,建議閱讀《 HTTP: The Definitive Guide 》補充知識。