前言

目前这个网站就是自己用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) {
    //...
}
复制代码

讲的比较直观,如果你有什么问题疑惑欢迎留言,看到第一时间答复