golang高性能HTTP路由处理插件库httprouter的使用
Golang高性能HTTP路由处理插件库httprouter的使用
HttpRouter是一个轻量级高性能的Go语言HTTP请求路由器(也称为多路复用器或简称mux)。
特性
- 仅明确匹配:每个请求只能精确匹配一条路由或没有匹配
- 自动处理斜杠:自动重定向客户端处理多余或缺少的斜杠
- 路径自动校正:可以修正错误的大小写并移除多余的路径元素
- 路由模式中的参数:路径参数非常高效
- 零垃圾:匹配和调度过程不产生垃圾
- 最佳性能:基准测试表明性能优异
- 防止服务器崩溃:可以设置Panic处理器
- 完美的API支持:内置对OPTIONS请求和405 Method Not Allowed响应的支持
安装
$ go get github.com/julienschmidt/httprouter
基本使用示例
package main
import (
"fmt"
"net/http"
"log"
"github.com/julienschmidt/httprouter"
)
// 首页处理器
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))
}
命名参数
:name
是一个命名参数。可以通过httprouter.Params
访问参数值:
func Hello(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
fmt.Fprintf(w, "hello, %s!\n", ps.ByName("name"))
}
命名参数只匹配单个路径段:
Pattern: /user/:user
/user/gordon match
/user/you match
/user/gordon/profile no match
/user/ no match
捕获所有参数
捕获所有参数的形式为*name
,必须放在模式末尾:
Pattern: /src/*filepath
/src/ match
/src/somefile.go match
/src/subdir/somefile.go match
静态文件服务
// 从./public目录提供静态文件
router.NotFound = http.FileServer(http.Dir("public"))
更干净的方法是为文件服务使用单独的子路径:
router.ServeFiles("/static/*filepath", http.Dir("public"))
中间件示例
基本认证中间件
func BasicAuth(h httprouter.Handle, requiredUser, requiredPassword string) httprouter.Handle {
return func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
user, password, hasAuth := r.BasicAuth()
if hasAuth && user == requiredUser && password == requiredPassword {
h(w, r, ps)
} else {
w.Header().Set("WWW-Authenticate", "Basic realm=Restricted")
http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized)
}
}
}
// 使用
router.GET("/protected/", BasicAuth(Protected, "user", "pass"))
多域名/子域名处理
type HostSwitch map[string]http.Handler
func (hs HostSwitch) ServeHTTP(w http.ResponseWriter, r *http.Request) {
if handler := hs[r.Host]; handler != nil {
handler.ServeHTTP(w, r)
} else {
http.Error(w, "Forbidden", 403)
}
}
func main() {
router := httprouter.New()
router.GET("/", Index)
router.GET("/hello/:name", Hello)
hs := make(HostSwitch)
hs["example.com:12345"] = router
log.Fatal(http.ListenAndServe(":12345", hs))
}
CORS支持
router.GlobalOPTIONS = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.Header.Get("Access-Control-Request-Method") != "" {
header := w.Header()
header.Set("Access-Control-Allow-Methods", header.Get("Allow"))
header.Set("Access-Control-Allow-Origin", "*")
}
w.WriteHeader(http.StatusNoContent)
})
HttpRouter是一个高效、轻量级的HTTP路由器,特别适合构建RESTful API和高性能Web服务。
更多关于golang高性能HTTP路由处理插件库httprouter的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
更多关于golang高性能HTTP路由处理插件库httprouter的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
Golang高性能HTTP路由处理库httprouter使用指南
httprouter是一个轻量级、高性能的HTTP请求路由器(也称为多路复用器),专为Go语言设计。它比标准库的net/http
路由器更快,支持参数化路由,并且内存占用极低。
安装
go get github.com/julienschmidt/httprouter
基本使用
package main
import (
"fmt"
"log"
"net/http"
"github.com/julienschmidt/httprouter"
)
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))
}
核心特性
1. 参数化路由
httprouter支持在路径中定义参数:
router.GET("/user/:name", func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
name := ps.ByName("name")
fmt.Fprintf(w, "Hello %s", name)
})
2. 通配符路由
使用*
可以匹配任意路径:
router.GET("/static/*filepath", func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
filepath := ps.ByName("filepath")
fmt.Fprintf(w, "Requested file: %s", filepath)
})
3. 路由优先级
httprouter有明确的路由优先级规则:
- 静态路径优先于参数化路径
- 参数化路径优先于通配符路径
4. 自动处理OPTIONS请求和405错误
httprouter会自动处理OPTIONS请求,并返回405 Method Not Allowed错误。
高级用法
1. 自定义Panic处理
router.PanicHandler = func(w http.ResponseWriter, r *http.Request, err interface{}) {
log.Printf("Panic: %v", err)
http.Error(w, "Internal Server Error", http.StatusInternalServerError)
}
2. 自定义NotFound处理
router.NotFound = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusNotFound)
fmt.Fprintf(w, "404 Not Found")
})
3. 自定义MethodNotAllowed处理
router.MethodNotAllowed = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusMethodNotAllowed)
fmt.Fprintf(w, "405 Method Not Allowed")
})
4. 中间件支持
虽然httprouter本身不直接支持中间件,但可以很容易地包装处理函数:
func Logger(fn httprouter.Handle) httprouter.Handle {
return func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
start := time.Now()
fn(w, r, ps)
log.Printf("%s %s %v", r.Method, r.URL.Path, time.Since(start))
}
}
// 使用中间件
router.GET("/protected", Logger(ProtectedHandler))
性能优化技巧
- 避免在热路径中分配内存:在路由处理函数中避免不必要的内存分配
- 重用参数:如果可能,重用
httprouter.Params
对象 - 减少路由数量:合并相似的路由,使用参数化路由
- 使用sync.Pool:对于频繁创建的对象,考虑使用sync.Pool
与标准库对比
httprouter相比标准库net/http
的ServeMux
有以下优势:
- 更快的路由查找
- 支持路径参数
- 明确的路由优先级
- 更少的内存占用
- 自动处理OPTIONS和405
完整示例
package main
import (
"encoding/json"
"fmt"
"log"
"net/http"
"github.com/julienschmidt/httprouter"
)
type User struct {
ID string `json:"id"`
Name string `json:"name"`
}
var users = map[string]User{
"1": {ID: "1", Name: "Alice"},
"2": {ID: "2", Name: "Bob"},
}
func GetUser(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
id := ps.ByName("id")
user, exists := users[id]
if !exists {
w.WriteHeader(http.StatusNotFound)
return
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(user)
}
func CreateUser(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
var user User
err := json.NewDecoder(r.Body).Decode(&user)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
return
}
users[user.ID] = user
w.WriteHeader(http.StatusCreated)
}
func main() {
router := httprouter.New()
// 设置自定义处理器
router.NotFound = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(404)
fmt.Fprint(w, "Custom 404 Page")
})
// 路由定义
router.GET("/users/:id", GetUser)
router.POST("/users", CreateUser)
// 静态文件服务
router.ServeFiles("/static/*filepath", http.Dir("./public"))
log.Println("Server started on :8080")
log.Fatal(http.ListenAndServe(":8080", router))
}
httprouter是构建高性能HTTP服务的优秀选择,特别适合需要高效路由和参数化路径的应用程序。