下一篇 Go聖經-學習筆記之error接口github
package http type Handler interface{ ServeHTTP(w ResponseWriter, r *Request) } func ListenAndServe(address string, h Handler) error
經過運行指定的服務端口,把全部該端口的客戶端請求所有轉發給h作分發處理,Go聖經舉了一個獲取各個商品價格的例子:golang
func main() { db := database{"shoes": 50, "socks": 5} log.Fatal(http.ListenAndServe("localhost:8000", db)) } type dollars float32 func (d dollars) String() string { return fmt.Sprintf("$%.2f", d) } type database map[string]dollars func (db database) ServeHTTP(w http.ResponseWriter, req *http.Request) { for item, price := range db { fmt.Fprintf(w, "%s: %s\n", item, price) } }
因此,若是咱們要設計一個web服務的路由框架,則就是經過隱式實現ServeHTTP接口作的,通常作法:首先創建好路由樹或者路由表,而後啓動服務,當一個請求到達服務端後,首先經過ServeHTTP處理客戶端的路由是否在路由樹或者路由表中存在,若是不存在,直接報404頁面沒發現的錯誤。不然,由路由樹分發後的api處理請求。例如:httprouter一個輕量級且高性能的路由請求框架。web
package main import ( "fmt" "github.com/julienschmidt/httprouter" "net/http" "log" ) func Index(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { fmt.Fprint(w, "Welcome!\n") } func Hello(w http.ResponseWriter, r *http.Request, ps httprouter.Params) { fmt.Fprintf(w, "hello, %s!\n", ps.ByName("name")) } func main() { router := httprouter.New() router.GET("/", Index) router.GET("/hello/:name", Hello) log.Fatal(http.ListenAndServe(":8080", router)) }
/
和/hello/:name
,;/
, 則有分發後的Index接口處理請求;/hello/:name
,則由分發後的Hello接口處理該請求;路由也支持正則表達式,主要看本身的設計了。入口爲ServeHTTP路由分發。正則表達式
Go語言標準庫http自帶路由分發功能:api
mux:=http.NewServeMux() mux.Handle("/", http.HandlerFunc(Index)) mux.Handle("/hello/:name", http.HandlerFunc(Hello)) log.Fatal(http.ListenAndServe("localhost:8000", mux) // ServeMux實現了ServeHTTP方法 // 或者 http.HandleFunc("/", Index) // 內部有一個全局的ServeMux, 因此咱們通常不用上面的使用方法 http.HandleFunc("/hello/:name" Hello)
ServeMux是利用map[pattern]handler數據結構實現的,不支持正則路由,也就基本上不支持RESTful路由,推薦兩個路由框架:數據結構
對於第一個路由,吐槽比較多的地方:1. 不更新;2.正則和非正則路由有衝突,能夠看我提的issue;框架