前言
目前这个网站就是自己用iris新搭的,需求和功能也在一步一步的完善。前两篇已经发布快一个星期了,慢慢也收到了一些反馈。其中就有说到iris作者之前的一些种种行为,而使大家对iris库略有偏见。但对于我来说,一个技术宅,只关心技术本身的价值,而不会去关心作者的是非。
接下来进入主题,今天解析Middleware和Router部分。
Middleware的用途
顾名思义,Middleware就是中间件。很直观点,可以理解为是一座桥、一扇门、一根网线之类,具有连接、传输作用的媒介。 在iris中Middleware可以拆解一个复杂的过程为多个步骤。 在此我解析一下它的逻辑和实现,至于应用场景,可以针对平时工作中的业务逻辑而定。
Middleware逻辑解析
来看一下作者给出的例子(为了方便说明,分别给注释加了编号)
//1 First mount static files
iris.StaticWeb("/assets", "./public/assets")
//2 Then declare which middleware to use (custom or not)
iris.Use(myMiddleware{})
iris.UseFunc(func(ctx *iris.Context){})
//3 declare any finish middleware/ runs always at the end of the request using .Done/.DoneFunc
iris.DoneFunc(executeLast)
//4 Now declare routes
iris.Get("/myroute", func(ctx *iris.Context) {
// do stuff
})
iris.Get("/secondroute", myMiddlewareFunc, myRouteHandlerfunc)
//5 Now run the server
iris.Listen(":8080")
//6 executeLast func middleware
func executeLast(ctx *iris.Context){
println("before close the http request")
}
//7 myMiddleware will be like that
type myMiddleware struct {
// your 'stateless' fields here
}
//8
func (m myMiddleware) Serve(ctx *iris.Context){
// ...
}
复制代码
要想完全弄明白Middleware,这段代码就够了,下来我们一起来看一下里面的点
iris.Useiris.UseFuncstruct函数
struct格式
Serve
Handlerfunc (m myMiddleware) Serve(ctx *iris.Context)
其实这个格式就是前面讲过的Handler。看注释的7和8,是不是和前面的Handler实现一模一样。
iris.Use(myMiddleware{})
Func格式
server
iris.UseFunciris.DoneFunc
文件:iris.go
// UseFunc registers HandlerFunc middleware
// returns itself
func (api *muxAPI) UseFunc(handlersFn ...HandlerFunc) MuxAPI {
return api.Use(convertToHandlers(handlersFn)...)
}
文件:http.go
// convertToHandlers just make []HandlerFunc to []Handler, although HandlerFunc and Handler are the same
// we need this on some cases we explicit want a interface Handler, it is useless for users.
func convertToHandlers(handlersFn []HandlerFunc) []Handler {
hlen := len(handlersFn)
mlist := make([]Handler, hlen)
for i := 0; i < hlen; i++ {
mlist[i] = Handler(handlersFn[i])
}
return mlist
}
复制代码
iris.DoneFunc
特别提示,而这两个函数最大的区别就是:一个在Router之前执行,一个在所有Router之后执行
Middleware用法
看代码中的这一句
iris.Get("/secondroute", myMiddlewareFunc, myRouteHandlerfunc)
复制代码
这里分别一次调用了两个函数,他们的依次执行。但是又有一个点就是:在这里调用的函数是不是就不需要实现Handler了,其实不是,同样也是要实现的。具体怎么实现,我们来看一下:
func myMiddlewareFunc(ctx *iris.Context){
ctx.Writef("1. This is the first middleware\n")
ctx.Next()
}
func myRouteHandlerfunc(ctx *iris.Context) {
ctx.Writef("2. This is the second middleware \n")
ctx.Next()
}
复制代码
ctx.Next()
// Next calls all the next handler from the middleware stack, it used inside a middleware
func (ctx *Context) Next() {
//set position to the next
ctx.Pos++
midLen := len(ctx.Middleware)
//run the next
if ctx.Pos < midLen {
ctx.Middleware[ctx.Pos].Serve(ctx)
}
}
复制代码
Next()Server
但同时,Next()还有自己的含义,就是是否还执行后面的Middleware方法(例如上面的例子,myMiddlewareFunc中没有调用Next(),就不会执行myRouteHandlerfunc)
总结
所以,其实Middleware就是Handler,只是做了不同的实现逻辑,因此可以满足不同的业务逻辑 通过Next()方法串行的将多个Middleware连接起来,依次执行
Router
至于Router,iris的路由解析还是比较弱的。这其实也性能上快的一种方式吧。 如果路由解析很强大,必然要支持正则,这样会降低一些性能。
- 由于很简单,就只贴一段代码,大家看看吧
其中包含了几种方式:GET, POST, PUT, DELETE, HEAD, PATCH & OPTIONS
package main
import "github.com/kataras/iris"
func main() {
// declare the routes
iris.Get("/home", testGet)
iris.Post("/login", testPost)
iris.Put("/add", testPut)
iris.Delete("/remove", testDelete)
iris.Head("/testHead", testHead)
iris.Patch("/testPatch", testPatch)
iris.Options("/testOptions", testOptions)
iris.Connect("/testConnect", testConnect)
iris.Trace("/testTrace", testTrace)
// start the server
iris.Listen(":8080")
}
func testGet(ctx *iris.Context) {
//...
}
func testPost(ctx *iris.Context) {
//...
}
复制代码
讲的比较直观,如果你有什么问题疑惑欢迎留言,看到第一时间答复