Go bunrouter
最后修改时间 2024 年 4 月 11 日
在本文中,我们将展示如何在 Golang 中使用 bunrouter 创建 HTTP 路由。
路由将 HTTP 动词(如 GET、POST、PUT、DELETE)和 URL 路径关联到处理函数。路由器是一个创建路由的对象;也就是说,它将 HTTP 请求映射到处理函数。
bunrouter
是一个快速灵活的 Go HTTP 路由器。它支持中间件、路由分组和灵活的错误处理。它与内置的 net/http
API 兼容。
Go bunrouter 简单示例
在第一个示例中,我们使用 bunrouter 设置了一个简单的服务器。
package main import ( "log" "net/http" "github.com/uptrace/bunrouter" ) func main() { router := bunrouter.New() router.GET("/", func(w http.ResponseWriter, req bunrouter.Request) error { w.Write([]byte("index")) return nil }) log.Println("listening on https://:8080") log.Println(http.ListenAndServe(":8080", router)) }
服务器响应 GET 请求并返回一个简短的消息。
import ( "log" "net/http" "github.com/uptrace/bunrouter" )
我们导入 github.com/uptrace/bunrouter
包。
router := bunrouter.New()
创建一个新的 bunrouter。
router.GET("/", func(w http.ResponseWriter, req bunrouter.Request) error { w.Write([]byte("index")) return nil })
我们创建一个 GET 路由。匿名处理函数响应 "index" 消息。
Go bunrouter notfound 处理程序
在下一个示例中,我们设置了 notfound 处理程序。它用于处理没有匹配路由的请求。
package main import ( "fmt" "log" "net/http" "github.com/uptrace/bunrouter" ) func main() { router := bunrouter.New( bunrouter.WithNotFoundHandler(notFoundHandler), ) router.GET("/hello", func(w http.ResponseWriter, req bunrouter.Request) error { fmt.Fprintf(w, "hello") return nil }) log.Println("listening on https://:8080") log.Println(http.ListenAndServe(":8080", router)) } func notFoundHandler(w http.ResponseWriter, req bunrouter.Request) error { w.WriteHeader(http.StatusNotFound) fmt.Fprintf(w, "404 - failed to find %s", req.URL.Path) return nil }
代码委托给 notFoundHandler
函数。
router := bunrouter.New( bunrouter.WithNotFoundHandler(notFoundHandler), )
使用 WithNotFoundHandler
注册 notfound 处理程序。
func notFoundHandler(w http.ResponseWriter, req bunrouter.Request) error { w.WriteHeader(http.StatusNotFound) fmt.Fprintf(w, "404 - failed to find %s", req.URL.Path) return nil }
在 notFoundHandler
中,我们设置状态码和错误消息。
$ curl localhost:8080/about 404 - failed to find /about
方法不允许
HTTP 405 Method Not Allowed 响应状态码表示服务器知道请求方法,但目标资源不支持该方法。
例如,我们有一个只响应 GET 请求的路由。如果我们发送 POST 请求,服务器就可以响应 405 Method Not Allowed 消息。默认情况下,bunrouter 在这种情况下什么也不做。
package main import ( "fmt" "log" "net/http" "github.com/uptrace/bunrouter" ) func main() { router := bunrouter.New(bunrouter.WithMethodNotAllowedHandler(methodNotAllowedHandler)) router.GET("/", func(w http.ResponseWriter, req bunrouter.Request) error { fmt.Fprintln(w, "index") return nil }) log.Println("listening on https://:8080") log.Println(http.ListenAndServe(":8080", router)) } func methodNotAllowedHandler(w http.ResponseWriter, req bunrouter.Request) error { w.WriteHeader(http.StatusMethodNotAllowed) fmt.Fprintln(w, "405 - method not allowed") return nil }
在示例中,我们使用 bunrouter.WithMethodNotAllowedHandler
函数设置方法不允许处理程序。
$ curl localhost:8080/ index $ curl localhost:8080/ -d "name=Peter" 405 - method not allowed
Go bunrouter POST 请求
HTTP POST 方法将数据发送到服务器。它通常用于上传文件或提交完成的 Web 表单。
package main import ( "fmt" "log" "net/http" "github.com/uptrace/bunrouter" ) func main() { router := bunrouter.New() router.GET("/", func(w http.ResponseWriter, req bunrouter.Request) error { fmt.Fprintln(w, "index") return nil }) router.POST("/", func(w http.ResponseWriter, req bunrouter.Request) error { err := req.ParseForm() if err != nil { http.Error(w, fmt.Sprint(err), http.StatusUnprocessableEntity) } fmt.Fprintln(w, req.Form) return nil }) log.Println("listening on https://:8080") log.Println(http.ListenAndServe(":8080", router)) }
该示例处理 POST 请求。
err := req.ParseForm()
ParseForm
函数解析请求体并将任何数据填充到 Req.Form
中。
if err != nil { http.Error(w, fmt.Sprint(err), http.StatusUnprocessableEntity) }
如果发生错误,我们使用 http.Error
函数发送错误消息。
路由分组
路由功能可以组织成组。
package main import ( "fmt" "log" "net/http" "github.com/uptrace/bunrouter" ) func main() { router := bunrouter.New() router.WithGroup("/api/", func(group *bunrouter.Group) { group.GET("/index", index) group.GET("/hello", hello) }) router.WithGroup("/api2/", func(group *bunrouter.Group) { group.GET("/index", index2) group.GET("/hello", hello2) }) log.Println("listening on https://:8080") log.Println(http.ListenAndServe(":8080", router)) } func index(w http.ResponseWriter, req bunrouter.Request) error { fmt.Fprintln(w, "index") return nil } func hello(w http.ResponseWriter, req bunrouter.Request) error { fmt.Fprintln(w, "hello") return nil } func index2(w http.ResponseWriter, req bunrouter.Request) error { fmt.Fprintln(w, "index2") return nil } func hello2(w http.ResponseWriter, req bunrouter.Request) error { fmt.Fprintln(w, "hello2") return nil }
在示例中,我们有两个组:/api/
和 /api2/
。
router.WithGroup("/api/", func(group *bunrouter.Group) { group.GET("/index", index) group.GET("/hello", hello) })
使用 WithGroup
创建一个新组。
$ curl localhost:8080/api/index index $ curl localhost:8080/api/hello hello $ curl localhost:8080/api2/hello hello2 $ curl localhost:8080/api2/index index2
来源
在本文中,我们使用了 bunrouter。