字节赫兹 框架教程 二 Routers(1)https://developer.aliyun.com/article/1391747
通配参数路由
Hertz 支持使用 *path 这样的通配参数设置路由,并且通配参数会匹配所有内容。
如果我们设置/src/*path路由,匹配情况如下
路径 | 是否匹配 |
/src/ | 匹配 |
/src/somefile.go | 匹配 |
/src/subdir/somefile.go | 匹配 |
通过使用 RequestContext.Param 方法,我们可以获取路由中携带的参数。
示例代码:
package main import ( "context" "github.com/cloudwego/hertz/pkg/app" "github.com/cloudwego/hertz/pkg/app/server" "github.com/cloudwego/hertz/pkg/protocol/consts" ) func main(){ h := server.Default(server.WithHostPorts("127.0.0.1:8080")) // However, this one will match "/hertz/v1/" and "/hertz/v2/send" h.GET("/hertz/:version/*action", func(ctx context.Context, c *app.RequestContext) { version := c.Param("version") action := c.Param("action") message := version + " is " + action c.String(consts.StatusOK, message) }) h.Spin() }
在浏览器访问http://localhost:8080/hertz/my/study的结果
使用匿名函数与装饰器注册路由
在使用匿名函数或装饰器注册路由时,如果我们使用 RequestContext.HandlerName() 获取 handler 名称则会获取到错误的名称。
这里需要使用 Hertz 提供的 GETEX、POSTEX、PUTEX、DELETEEX、HEADEX、AnyEX、HandleEX 方法并手动传入 handler 名称注册路由,使用 app.GetHandlerName 获取 handler 名称。
示例代码:
package main import ( "context" "github.com/cloudwego/hertz/pkg/app" "github.com/cloudwego/hertz/pkg/app/server" "github.com/cloudwego/hertz/pkg/protocol/consts" ) func main() { h := server.Default() h.AnyEX("/ping", func(c context.Context, ctx *app.RequestContext) { ctx.String(consts.StatusOK, app.GetHandlerName(ctx.Handler())) }, "ping_handler") h.Spin() }
获取路由注册信息
Hertz 提供了 Routes 获取注册的路由信息供用户使用。
路由信息结构:
// RouteInfo represents a request route's specification which contains method and path and its handler. type RouteInfo struct { Method string // http method Path string // url path Handler string // handler name HandlerFunc app.HandlerFunc } // RoutesInfo defines a RouteInfo array. type RoutesInfo []RouteInfo 示例代码: package main import ( "context" "github.com/cloudwego/hertz/pkg/app" "github.com/cloudwego/hertz/pkg/app/server" "github.com/cloudwego/hertz/pkg/common/hlog" "github.com/cloudwego/hertz/pkg/common/utils" "github.com/cloudwego/hertz/pkg/protocol/consts" ) func main() { h := server.Default() h.GET("/ping", func(c context.Context, ctx *app.RequestContext) { ctx.JSON(consts.StatusOK, utils.H{"ping": "pong"}) }) routeInfo := h.Routes() hlog.Info(routeInfo) h.Spin() }
NoRoute 与 NoMethod 使用
Hertz 提供了 NoRoute 与 NoMethod 方法用于全局处理 HTTP 404 与 405 请求。 当使用 NoMethod 时需要与 WithHandleMethodNotAllowed 配合使用。
示例代码:
package main import ( "context" "github.com/cloudwego/hertz/pkg/app" "github.com/cloudwego/hertz/pkg/app/server" "github.com/cloudwego/hertz/pkg/common/utils" "github.com/cloudwego/hertz/pkg/protocol/consts" ) func main() { h := server.Default(server.WithHandleMethodNotAllowed(true)) h.POST("/ping", func(c context.Context, ctx *app.RequestContext) { ctx.JSON(consts.StatusOK, utils.H{"ping": "pong"}) }) // set NoRoute handler h.NoRoute(func(c context.Context, ctx *app.RequestContext) { ctx.String(consts.StatusOK, "no route") }) // set NoMethod handler h.NoMethod(func(c context.Context, ctx *app.RequestContext) { ctx.String(consts.StatusOK, "no method") }) h.Spin() }
重定向尾斜杠
Hertz 在默认情况下会根据请求 path 末尾的 / 自动进行转发。如果 router 中只有 /foo/,那么请求 /foo 会被自动重定向到 /foo/;如果 router 中只有 /foo,那么 /foo/ 会被重定向到 /foo。
这样的请求除 GET 以外的请求方法都会触发 307 Temporary Redirect 状态码,而 GET 请求会触发 301 Moved Permanently 状态码。
可以在配置中取消,如下:
package main import "github.com/cloudwego/hertz/pkg/app/server" func main() { h := server.New(server.WithRedirectTrailingSlash(false)) ... }