golang高性能HTTP路由处理插件库httprouter的使用

Golang高性能HTTP路由处理插件库httprouter的使用

HttpRouter是一个轻量级高性能的Go语言HTTP请求路由器(也称为多路复用器或简称mux)。

特性

  1. 仅明确匹配:每个请求只能精确匹配一条路由或没有匹配
  2. 自动处理斜杠:自动重定向客户端处理多余或缺少的斜杠
  3. 路径自动校正:可以修正错误的大小写并移除多余的路径元素
  4. 路由模式中的参数:路径参数非常高效
  5. 零垃圾:匹配和调度过程不产生垃圾
  6. 最佳性能:基准测试表明性能优异
  7. 防止服务器崩溃:可以设置Panic处理器
  8. 完美的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

1 回复

更多关于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有明确的路由优先级规则:

  1. 静态路径优先于参数化路径
  2. 参数化路径优先于通配符路径

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))

性能优化技巧

  1. 避免在热路径中分配内存:在路由处理函数中避免不必要的内存分配
  2. 重用参数:如果可能,重用httprouter.Params对象
  3. 减少路由数量:合并相似的路由,使用参数化路由
  4. 使用sync.Pool:对于频繁创建的对象,考虑使用sync.Pool

与标准库对比

httprouter相比标准库net/httpServeMux有以下优势:

  • 更快的路由查找
  • 支持路径参数
  • 明确的路由优先级
  • 更少的内存占用
  • 自动处理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服务的优秀选择,特别适合需要高效路由和参数化路径的应用程序。

回到顶部