golang常用库之gorilla/mux-http路由库使用详解

golang常用库:gorilla/mux-http路由库使用
golang常用库:配置文件解析库-viper使用
golang常用库:操作数据库的orm框架-gorm基本使用

一:golang自带路由介绍

golang自带路由库 http.ServerMux ,实际上是一个 map[string]Handler,是请求的url路径和该url路径对于的一个处理函数的映射关系。这个实现比较简单,有一些缺点:

不支持参数设定,例如/user/:uid 这种泛型类型匹配无法很友好的支持REST模式,无法限制访问方法(POST,GET等)也不支持正则

二:gorilla/mux路由

github地址:https://github.com/gorilla/mux
http://www.gorillatoolkit.org/pkg/mux
https://github.com/gorilla/mux#examples

上面所指出来的glang自带路由的缺点,gorilla/mux 都具备,而且还兼容 http.ServerMux。除了支持路径正则,命名路由,还支持中间件等等功能。所以mux是一个短小精悍,功能很全的路由。

1. 普通路由

示例 demo1.go

package main

import (
	"fmt"
	"github.com/gorilla/mux"
	"net/http"
)

func main() {
	r := mux.NewRouter()
	//普通路由
	r.HandleFunc("/", IndexHandler)
	r.HandleFunc("/products", ProductsHandler)

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

func IndexHandler(w http.ResponseWriter, r *http.Request) {
	w.WriteHeader(http.StatusOK)
	fmt.Fprintf(w, "hello world")
}

func ProductsHandler(w http.ResponseWriter, r *http.Request) {
	w.WriteHeader(http.StatusOK)
	fmt.Fprintf(w, "hello, Products")
}

上面mux的普通路由是不是似曾相识,跟golang标准库用法一样

在浏览器访问:http://localhost:8080/products
输出:hello, Products

2. 参数路由

参数路由,可以是普通路由,还可以是正则匹配
示例 demo2.go:

package main

import (
	"net/http"

	"fmt"

	"github.com/gorilla/mux"
)

//路由参数
func main() {
	r := mux.NewRouter()
	//1. 普通路由参数
	// r.HandleFunc("/articles/{title}", TitleHandler)

	//2. 正则路由参数,下面例子中限制为英文字母
	r.HandleFunc("/articles/{title:[a-z]+}", TitleHandler)

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

//https://github.com/gorilla/mux#examples
func TitleHandler(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r) // 获取参数
	w.WriteHeader(http.StatusOK)
	fmt.Fprintf(w, "title: %v\n", vars["title"])
}


第1个普通路由参数,就是啥参数都可以,不管是字母,数字,还是中文等
第2个正则路由参数,限制了只能是英文字母,否则会报 404 page not found

3. 路由匹配Matching Routes

https://github.com/gorilla/mux#matching-routes
我们也可以限制路由或者子路由。

3.1 匹配host

r := mux.NewRouter()
//只匹配 www.example.com
r.Host("www.example.com")
// 动态匹配子路由
r.Host("{subdomain:[a-z]+}.example.com")

3.2 更多的一些其他匹配

见下面的更多匹配的例子:

r := mux.NewRouter()

r.PathPrefix("/products/") //前缀匹配
r.Methods("GET", "POST") //请求方法匹配
r.Schemes("https") //schemes
r.Headers("X-Requested-With", "XMLHttpRequest") //header 匹配
r.Queries("key", "value") //query的值匹配

// 用户自定义方法 匹配
r.MatcherFunc(func(r *http.Request, rm *RouteMatch) bool { 
 return r.ProtoMajor == 0
})

把上面的联合起来在一个单独的route里

r.HandleFunc("/products", ProductsHandler).
 Host("www.example.com").
 Methods("GET").
 Schemes("http")

3.3 子路由匹配

Subrouter()可以设置子路由

r := mux.NewRouter()
s := r.Host("www.example.com").Subrouter()

s.HandleFunc("/products/", ProductsHandler)
s.HandleFunc("/products/{key}", ProductHandler)
s.HandleFunc("/articles/{category}/{id:[0-9]+}", ArticleHandler)

3.4 多个路由匹配的顺序

如果有多个路由添加到路由器里面,那么匹配顺序是怎么样?按照添加的先后顺序匹配。比如有2个路由都匹配了,那么优先匹配第一个路由。

r := mux.NewRouter()
r.HandleFunc("/specific", specificHandler)
r.PathPrefix("/").Handler(catchAllHandler)

4. 设置路由前缀

PathPrefix()设置路由前缀

r := mux.NewRouter()

//PathPrefix() 可以设置路由前缀
product := r.PathPrefix("/products").HandleFunc("/", ProductsHandler)

路由前缀一般情况下不会单独使用,而是和子路由结合起来用,实现路由分组

golang常用库之gorilla/mux-http路由库使用详解

扫一扫手机访问