【Go + Nuxt.js 搭建一个 BBS 系统】4. 深入Iris mvc

交流 Go语言分享
0 / 210

点击下面链接购买后可获取本课程完整源码,同时提供高大上的在线IDE开发环境,边看教程边动手。

作者简介

大猫猫,互联网公司老码农、不折腾不舒服斯基,多年千万日活服务端研发和架构经验。关注公众号查看更多技术干货:

码农俱乐部

实验介绍

实验内容

上面的章节中我们对Iris有了初步的认识,那么接下来我们继续接着上个章节的内容更加深入的讲些一下Iris的特性:控制器 (controller),中间件 (middleware)。

知识点

  • Iris 控制器 (controller)
  • Iris 中间件 (middleware)

控制器 (controller)

控制器是Iris支持的重要特性之一,他能够非常清晰、方便的去定义和管理接口。 Iris controller 的设计思想是约定优于配置,只要按照他Iris的约定规则来编写代码即可很简单地完成一个controller,下面我们通过一个实例来了解一下,代码如下:

package main

import (
	"github.com/kataras/iris"
	"github.com/kataras/iris/mvc"

	"github.com/kataras/iris/middleware/logger"
	"github.com/kataras/iris/middleware/recover"
)

func main() {
	app := iris.New()
	app.Logger().SetLevel("debug")
	app.Use(recover.New())
	app.Use(logger.New())

	mvc.Configure(app.Party("/root"), func(mvcApp *mvc.Application) {
		mvcApp.Handle(new(MyController))
	})

	_ = app.Run(iris.Addr(":8080"), iris.WithoutServerError(iris.ErrServerClosed))
}

type MyController struct {
	Ctx iris.Context
}

// GET: http://localhost:8080/root
func (m *MyController) Get() string {
	return "Hey"
}

// GET: http://localhost:8080/root/123
func (m *MyController) GetBy(id int64) interface{} {
	return map[string]interface{}{"id": id}
}

// GET: http://localhost:8080/root/hello/world
func (m *MyController) GetHelloWorld() interface{} {
	return map[string]string{"message": "Hello world!"}
}

// GET: http://localhost:8080/root/hello
func (m *MyController) GetHello() interface{} {
	return map[string]string{"message": "Hello Iris!"}
}

// Any: http://localhost:8080/root/test
func (m *MyController) AnyTest() {
	_, _ = m.Ctx.HTML("<h1>test</h1>")
}

上面代码中我们定义了一个 controller 叫做 MyController,在该MyController中定义了几个接口,这些接口的访问路径都在接口路径都写在注释中了。通过总结这些函数的访问路径,我们可以简单的得到以下结论:

  • controller的路由规则为:HttpMethod + FuncName(函数名会根据驼峰命名法进行分割),其中HttpMethod限定该接口的请求类型,FuncName限定接口的路径;
  • controller中函数名以Any开头标识该接口不限定请求类型,任何类型的请求都可以正常访问。
  • controller中函数名称结尾带By关键字的,接受一个输入参数,例如GetBy

方法名的前缀为HttpMethod,用来定义当前接口的请求类型,你还可以使用更多的 HttpMethod,例如:

func (m *MyController) Post() {}
func (m *MyController) Put() {}
func (m *MyController) Delete() {}
func (m *MyController) Connect() {}
func (m *MyController) Head() {}
func (m *MyController) Patch() {}
func (m *MyController) Options() {}
func (m *MyController) Trace() {}

func (m *MyController) All() {}
// OR
func (m *MyController) Any() {}

虽然controller中根据命名规则来定义访问路径非常的简单好用,能满足我们绝大部分的日常使用需求,但是一些复杂的路径规则还是无法适用,iris很人性化的考虑到了这一点,所以它提出了一个BeforeActivation概念。

BeforeActivation会在controller适配之前调用,在BeforeActivation中你可以自定义路由,我们通过下面的例子来了解它的使用方式:

func (this *MyController) BeforeActivation(b mvc.BeforeActivation) {
	// 1-> Method
	// 2-> Path
	// 3-> The controller's function name to be parsed as handler
	// 4-> Any handlers that should run before the MyCustomHandler
	b.Handle("GET", "/something/{id:long}", "MyCustomHandler")
}

// GET: http://localhost:8080/root/something/{id:long}
func (m *MyController) MyCustomHandler(id int64) string {
	return "MyCustomHandler says Hey"
}

那么这个时候我们就为MyController新增了一个接口,通过路径/something/{id:long}就能够访问到该接口了。

中间件 (middleware)

中间件可以在controller执行前或者执行后执行某个操作。如果你熟悉 Java 的话,就很容易理解中间件,我们可以将它看做是 Java 中的ServletFilter

利用中间件我们可以将一些通用的操作全部抽象到中间件中,而不必将这些通用的代码放到每个controller中,以此来减少重复代码和代码的解耦。例如我们列出以下几个中间件常用的场景:

  • 权限控制
  • 接口签名
  • 访问统计

下面我们使用中间件实现一个接口访问次数统计功能,通过该 demo 来了解中间件的使用方式:

package main

import (
	"fmt"
	"strconv"

	"github.com/kataras/iris"
	"github.com/kataras/iris/context"
	"github.com/kataras/iris/mvc"

	"github.com/kataras/iris/middleware/logger"
	"github.com/kataras/iris/middleware/recover"
)

func main() {
	app := iris.New()
	app.Logger().SetLevel("debug")
	app.Use(recover.New())
	app.Use(logger.New())

	count := 0

	mvc.Configure(app.Party("/root"), func(mvcApp *mvc.Application) {
		mvcApp.Router.Use(func(context context.Context) {
			if context.Path() == "/root/test" {
				count++
				fmt.Println("/root/test 请求次数:" + strconv.Itoa(count))
			}
			context.Next() // 加上他让Web进程继续往下执行,否则不会执行controller方法
		})
		mvcApp.Handle(new(MyController))
	})

	_ = app.Run(iris.Addr(":8080"), iris.WithoutServerError(iris.ErrServerClosed))
}

type MyController struct {
	Ctx iris.Context
}

// Any: http://localhost:8080/root/test
func (m *MyController) AnyTest() {
	_, _ = m.Ctx.HTML("<h1>test</h1>")
}

执行之后,当每次请求/root/test接口的时候控制台输出的数量都会 + 1,输出如下:

Now listening on: http://localhost:8080
Application started. Press CMD+C to shut down.
/root/test 请求次数:1
[INFO] 2019/09/25 15:10 200 225.36µs ::1 GET /root/test
/root/test 请求次数:2
[INFO] 2019/09/25 15:10 200 320.677µs ::1 GET /root/test
/root/test 请求次数:3
[INFO] 2019/09/25 15:12 200 94.755µs ::1 GET /root/test

注意我们在中间件函数的最后需要加上context.Next(),该函数会告诉 iris 继续执行下面的 controller,否则代码不会执行到 controller。

总结

通过本章节的讲解,我们基本可以使用 Iris hold 住日常使用中的绝大部分场景了,但是Iris是一个伟大的框架,如果想要了解更多细节和高级用法可以去官网详细,系统的了解下。Iris官网:https://iris-go.com

文章转载请注明出处,原文链接:https://mlog.club/topic/646

回复