
Iris 对 MVC (Model View Controller) 模式有着非常好的支持,这是其它 go 语言框架所不具备。
Iris Web 框架支持以最快的方式执行,请求数据、模型、持久性数据和绑定。
特点
支持所有 HTTP 方法, 例如,如果想要写一个 GET
那么在控制器中也要写一个 Get()
函数,你可以在一个控制器内定义多个函数。
每个控制器通过 BeforeActivation
自定义事件回调,用来自定义控制器的结构的方法与自定义路径处理程序(甚至有正则表达式路径)。 例子:
import (
"github.com/kataras/iris"
"github.com/kataras/iris/mvc"
)
func main() {
app := iris.New()
mvc.Configure(app.Party("/root"), myMVC)
app.Run(iris.Addr(":8080"))
}
func myMVC(app *mvc.Application) {
// app.Register(...)
// app.Router.Use/UseGlobal/Done(...)
app.Handle(new(MyController))
}
type MyController struct {}
func (m *MyController) BeforeActivation(b mvc.BeforeActivation) {
// b.Dependencies().Add/Remove
// b.Router().Use/UseGlobal/Done // 和你已知的任何标准 API 调用
// 1-> 方法
// 2-> 路径
// 3-> 控制器函数的名称将被解析未一个处理程序 [ handler ]
// 4-> 任何应该在 MyCustomHandler 之前运行的处理程序[ handlers ]
b.Handle("GET", "/something/{id:long}", "MyCustomHandler", anyMiddleware...)
}
// GET: http://localhost:8080/root
func (m *MyController) Get() string { return "Hey" }
// GET: http://localhost:8080/root/something/{id:long}
func (m *MyController) MyCustomHandler(id int64) string { return "MyCustomHandler says Hey" }
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
通过定义一个附属的服务范围或者一个 Singleton
控制器范围,来实现控制器结构内部数据的持久化(在请求之间共享数据)。
在控制器之间共享依赖关系或者在父 MVC 应用程序上注册它们,以及在控制器里通过 BeforeActivation
可选回调事件,都可以修改每个控制器的依赖关系。 如 func(c *MyController) BeforeActivation(b mvc.BeforeActivation) { b.Dependencies().Add/Remove(...) }
。
访问控制器的字段 Context
(不需要手动绑定)如 Ctx iris.Context
或者当作方法参数输入,如 func(ctx iris.Context, otherArguments...)
。
控制器内部结构模型(在方法函数中设置并由视图呈现)。你可以从控制器的方法中返回模型,或者在请求生命周期中设置字段,并在相同的请求生命周期中将该字段返回到另一个方法。
正如你以前用过的一样,MVC 应用程序有自己的 Router
,它是一个 iris/router.Party
类型的标准 iris api。当 iris/router.Party
如期望的那样开始执行处理程序的时候 , Controllers
可以注册到任意的 Party
,包括子域。
BeginRequest(ctx)
是一个可选函数,经常用在方法执行前,执行一些初始化操作,当调用中间件或者有很多方法使用相同的数据集合的时候非常有用。
EndRequest(ctx)
是一个可选函数,经常用在方法执行后,执行一些初始化操作。
继承,递归,例如我们的 mvc.SessionController
,它有 Session *sessions.Session
和 Manager *sessions.Sessions
作为嵌入式字段,由 BeginRequest
加载, 这里 (opens new window). 这只是一个例子,你可以用使用管理器的 Start
返回的 sessions.Session
, 作为对 MVC 应用程序的动态依赖项。 如mvcApp.Register(sessions.New(sessions.Config{Cookie: "iris_session_id"}).Start)
.
通过控制器方法的输入参数访问动态路径参数,不需要绑定。当你使用 iris 的默认语法来解析控制器处理程序时,你需要在方法后加上 "." 字符,大写字母是一个新的子路径。 例子:
如果 mvc.New(app.Party("/user")).Handle(new(user.Controller))
func(*Controller) Get()
-GET:/user
.func(*Controller) Post()
-POST:/user
.func(*Controller) GetLogin()
-GET:/user/login
func(*Controller) PostLogin()
-POST:/user/login
func(*Controller) GetProfileFollowers()
-GET:/user/profile/followers
func(*Controller) PostProfileFollowers()
-POST:/user/profile/followers
func(*Controller) GetBy(id int64)
-GET:/user/{param:long}
func(*Controller) PostBy(id int64)
-POST:/user/{param:long}
如果 mvc.New(app.Party("/profile")).Handle(new(profile.Controller))
func(*Controller) GetBy(username string)
-GET:/profile/{param:string}
如果 mvc.New(app.Party("/assets")).Handle(new(file.Controller))
func(*Controller) GetByWildard(path string)
-GET:/assets/{param:path}
方法函数接收器支持的类型: int,int64, bool 和 string。
可选的响应输出参数,如下:
func(c *ExampleController) Get() string |
(string, string) |
(string, int) |
int |
(int, string) |
(string, error) |
error |
(int, error) |
(any, bool) |
(customStruct, error) |
customStruct |
(customStruct, int) |
(customStruct, string) |
mvc.Result or (mvc.Result, error)
2
3
4
5
6
7
8
9
10
11
12
13
14
15
mvc.Result (opens new window)是一个只包含: Dispatch(ctx iris.Context)
的 接口 (opens new window)。
# 范例
这个范例相当于 https://github.com/kataras/iris/blob/master/_examples/hello-world/main.go (opens new window)
似乎你必须要编写额外的代码,这个并不值当,但请记住,这个范例没有使用 iris mvc 功能,如 Model,Persistence 或者 View 引擎甚至没有使用 Session,它如此简单只是对于学习目的来说的,可能在你应用程序的任何地方都不会使用这么简单的控制器。
在我的个人笔记本电脑上,在每个 20MB 吞吐量的 "/ hello" 路径上使用 MVC 的这个例子的成本是大约 2MB,这对于大多数应用程序都是可以容忍,但你可以选择最适合你的 Iris, 低级处理程序 (low-level handlers) :性能或者高级控制器(high-level controllers):在开发大型应用程序上更易于维护和更少的代码实现。
请仔细阅读注释
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()
//(可选)添加两个内置处理程序(handlers)
//可以从任何与 http 相关的恐慌(http-relative panics) 中恢复
//并将请求记录到终端。
app.Use(recover.New())
app.Use(logger.New())
// "/" 服务于一个基于根路由的控制器。
mvc.New(app).Handle(new(ExampleController))
// http://localhost:8080
// http://localhost:8080/ping
// http://localhost:8080/hello
// http://localhost:8080/custom_path
app.Run(iris.Addr(":8080"))
}
// ExampleController 服务于 "/", "/ping" and "/hello" 路由。
type ExampleController struct{}
// Get serves
// Method: GET
// Resource: http://localhost:8080
func (c *ExampleController) Get() mvc.Result {
return mvc.Response{
ContentType: "text/html",
Text: "<h1>Welcome</h1>",
}
}
// GetPing serves
// Method: GET
// Resource: http://localhost:8080/ping
func (c *ExampleController) GetPing() string {
return "pong"
}
// GetHello serves
// Method: GET
// Resource: http://localhost:8080/hello
func (c *ExampleController) GetHello() interface{} {
return map[string]string{"message": "Hello Iris!"}
}
// BeforeActivation 会被调用一次,在控制器适应主应用程序之前
// 并且当然也是在服务运行之前
// 在版本 9 之后,你还可以为特定控制器的方法添加自定义路由。
// 在这个控制器,你可以注册自定义方法的处理程序。
// 使用带有 `ca.Router` 的标准路由
// 在不适用 mvc 的情况下,你可以做任何你可以做的事情
// 并将添加的依赖项绑定到
// 一个控制器的字段或者方法函数的输入参数中。
func (c *ExampleController) BeforeActivation(b mvc.BeforeActivation) {
anyMiddlewareHere := func(ctx iris.Context) {
ctx.Application().Logger().Warnf("Inside /custom_path")
ctx.Next()
}
b.Handle(
"GET",
"/custom_path",
"CustomHandlerWithoutFollowingTheNamingGuide",
anyMiddlewareHere,
)
// 或者甚至可以添加基于这个控制器路由的全局中间件,
// 比如在这个例子里面的根路由 "/" :
// b.Router().Use(myMiddleware)
}
// CustomHandlerWithoutFollowingTheNamingGuide serves
// Method: GET
// Resource: http://localhost:8080/custom_path
func (c *ExampleController) CustomHandlerWithoutFollowingTheNamingGuide() string {
return "hello from the custom handler without following the naming guide"
}
// GetUserBy serves
// Method: GET
// Resource: http://localhost:8080/user/{username:string}
// By 是一个保留的“关键字”来告诉框架你要
// 在函数的输入参数中绑定路径参数,它也是
// 有助于在同一个控制器中拥有 "Get“ 和 "GetBy"。
//
// func (c *ExampleController) GetUserBy(username string) mvc.Result {
// return mvc.View{
// Name: "user/username.html",
// Data: username,
// }
// }
/*
在一个控制器中可以使用多个 HTTP 方法,工厂会
为每条路由注册正确的 HTTP 方法,你可以按需取消注释:
func (c *ExampleController) Post() {}
func (c *ExampleController) Put() {}
func (c *ExampleController) Delete() {}
func (c *ExampleController) Connect() {}
func (c *ExampleController) Head() {}
func (c *ExampleController) Patch() {}
func (c *ExampleController) Options() {}
func (c *ExampleController) Trace() {}
*/
/*
func (c *ExampleController) All() {}
// 或者
func (c *ExampleController) Any() {}
func (c *ExampleController) BeforeActivation(b mvc.BeforeActivation) {
// 1 -> HTTP 方法
// 2 -> 路由路径
// 3 -> 控制器的方法名称应该是该路由的处理程序(handlers)。
b.Handle("GET", "/mypath/{param}", "DoIt", optionalMiddlewareHere...)
}
//激活后,所有依赖项都被设置 - 因此只能访问它们
//但仍可以添加自定义控制器或者简单的标准处理程序(handlers)。
func (c *ExampleController) AfterActivation(a mvc.AfterActivation) {}
*/
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
在控制器中以 HTTP 方法(Get
,Post
,Put
,Delete
...)为前缀的每个 exported
函数都可以作为 HTTP 端点调用。 在上面的示例中,所有函数都写入一个字符串到响应中。 请注意每种方法之前的注释。
HTTP 端点是 Web 应用程序中的可定位 URL(例如 http://localhost:8080/helloworld
),并结合使用的协议:HTTP,Web 服务器的网络位置(包括 TCP 端口):localhost:8080
和目标 URI /helloworld
。
第一条评论声明是一个 HTTP GET (opens new window) 方法, 它通过将 "/helloworld" 附加到基本 URL 来调用。第三个注释指定了 HTTP GET (opens new window) 方法, 该方法通过将 "/helloworld/welcome" 附加到URL来调用。
控制器通过By
关键字知道如何处理 GetBy
方法中的 “name” 或者GetWelcomeBy
方法中的 “name” 和 “numTimes”, 并且在没有样板的情况下构建动态路由;第三条注释指定了一个 HTTP GET (opens new window) 动态方法 ,该方法被以 "/helloworld/welcome" 开头的任何URL调用, URL另外两个路径部分:第一个部分可以接受任何值,第二个部分只能接受数字,即:"http://localhost:8080/helloworld/welcome/golang/32719 (opens new window)", 否则将会发送一个到 404 Not Found HTTP Error (opens new window) 客户端。
_examples/mvc (opens new window) 和 mvc/controller_test.go (opens new window) 文件用简单的范例解释来每个功能,它们展示了如何使用 Iris MVC Binder, Iris MVC Models 等等的优点...
对于 websocket 控制器请移步 Websockets 章节。