配置路由之前必须初始一个路由实例,如:r := zweb.New()
支持的基础函数如下所示:
r.GET(path string, handle znet.Handler)
r.POST(path string, handle znet.Handler)
r.PUT(path string, handle znet.Handler)
r.DELETE(path string, handle znet.Handler)
r.PATCH(path string, handle znet.Handler)
r.HEAD(path string, handle znet.Handler)
r.OPTIONS(path string, handle znet.Handler)
// 如需注册一个可以响应任何 HTTP 请求的路由可以使用 Any
r.Any(path string, handle znet.Handler)
r.GET("/hi", func(c *znet.Context) {
c.String(200, "Hello world")
})
r.POST("/ping", func(c *znet.Context) error {
c.String(200, "Hello ping")
// 如果返回错误会忽略上面的输出,转而输出 500 + err.Error()
// 可以通过 znet.RewriteErrorHandler 中间件自定义
return nil
})
// 还可以直接返回固定内容
r.GET("/ping", "pong")
r.GET("/info/{id:[\\d]+}", func(c *znet.Context) {
id := c.GetParam("id")
c.String(200, "Hello " + id)
})
// 内置了几个别名简写, :id :full(等同*)
// 如果非上面两个别名则等同 ([^\\/.]+)
// 上面写法可以简写为下面方式
r.GET("/info/:id", func(c *znet.Context) {
// 注意::id 内置是只匹配数字的
id := c.GetParam("id")
c.String(200, "Hello " + id)
})
r.GET("/user/*", func(c *znet.Context) {
// 注意:: 等同 .*
// 其实也可以 /user/{*:.*}
all:= c.GetParam("*")
c.String(200, all)
})
r.GET("/user/:name", func(c *znet.Context) {
// 注意::name 等同 ([^\\/.]+),不一定是要name 其他的英文字符也可以
name:= c.GetParam("name")
c.String(200, "Hello " + name)
})
// 多个匹配
r.GET(`/file/(?P<name>[\\w\\d-]+).(?P<ext>[a-zA-Z]+)`, func(c *znet.Context) {
file := c.GetParam("name")+"."+c.GetParam("ext")
c.String(200, file)
})
// 默认情况是把方法的名称转蛇形命名并且用 - 分隔的
// 有需要可以修改 znet.BindStructDelimiter = "_"
// 如果 BindStructDelimiter 为空则路由使用大驼峰而不是转蛇形命名
// 结构体 方法名:请求方式+路由(大驼峰)
type testController struct {}
// 路由组前缀
var prefix = "/test"
// 该方法在绑定路由之前执行
func (t *testController) Init(r *znet.Engine) error {
// 这里可以手动绑定一些特殊路由或者中间件之类
return nil
}
// Get /test/user
func (t *testController) GETUser(c *znet.Context) {}
// Post /test/user-info
func (t *testController) POSTUserInfo(c *znet.Context) {}
// 有三个特殊的前缀(ID,Full, Name)等同正则路由的 :id 与 :full(等同*)
// Get /test/user/:id
func (t *testController) IDGETUser(c *znet.Context) {}
// Get /test/user/:full
func (t *testController) FullGETUser(c *znet.Context) {}
// 绑定路由
err := r.BindStruct(prefix, &testController{})
支持直接给路由组或者单个路由注册
PS. 所有支持 net 标准库的中间件包都可使用
// r.Use(middleware ...znet.HandlerFunc)
// 给当前 r 注册一个中间件
r.Use(func(c *znet.Context) {
// 执行下一个 Handler
c.Next()
// 获取需要输出的内容
// c.PrevContent()
})
// 单独给 / 注册中间件,支持多个
r.GET("/", func(c *znet.Context) {
c.String(200, "哈哈")
},func(c *znet.Context) {
c.Log.Debug("中间件前置处理")
c.Next()
c.Log.Debug("中间件后置处理")
},func(c *znet.Context) {
c.Log.Debug("第二个中间件前置处理")
c.Next()
c.Log.Debug("第二个中间件后置处理")
})
优先级中间件 znet.WrapFirstMiddleware
默认情况下中间件是按传递的顺序执行的,假如想把某个中间件的执行时机提升至前面可以这样:
r.Use(func(c *znet.Context) {
c.Log.Debug(1)
c.Next()
c.Log.Debug(2)
})
r.GET("/", func(c *znet.Context) {
c.String(200, "哈哈")
},znet.WrapFirstMiddleware(func(c *znet.Context) {
c.Log.Debug(3)
c.Next()
c.Log.Debug(4)
}))
// 执行之后的打印顺序就是: 3, 1, 4, 2