AI写作智能体 自主规划任务,支持联网查询和网页读取,多模态高效创作各类分析报告、商业计划、营销方案、教学内容等。 广告
![](https://cdn.learnku.com/uploads/images/202002/06/16294/pTd8kXvfzk.png!large) 使用 Iris MVC 重构代码。 通过创建彼此独立的组件,开发人员可以在其他应用程序中快速轻松地重用组件。 可以将一个应用程序的相同(或相似)视图重构为具有不同数据的另一个应用程序,因为该视图只是处理数据向用户显示的方式。 Iris 拥有 **对MVC(模型视图控制器)架构模式的一流支持**, 在Go世界中其他任何地方都找不到这些东西。 你必须要引入 [iris/mvc](https://github.com/kataras/iris/tree/master/mvc) 子包。 ``` import "github.com/kataras/iris/v12/mvc" ``` Iris Web 框架以最快的执行速度支持请求数据,模型,持久性数据和绑定。 如果你不熟悉 Web 后台开发, 请先阅读MVC架构模式,这是一个很好的开始。 [wikipedia article](https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller). **特点** 支持所有 HTTP 方法,例如, 如果要提供`GET` 服务, 则控制器应具有一个名为 `Get()`的函数,你可以在同一控制器中定义多个方法函数。 每个控制器可以通过 `BeforeActivation` 自定义回调事件,自定义控制器的 struct 的方法用作具有自定义路径(甚至带有regex参数化的路径)的处理程序。 例如: ``` import ( "github.com/kataras/iris/v12" "github.com/kataras/iris/v12/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-> 将控制器的函数名称解析为处理程序 // 4-> 应该在 MyCustomHandler 之前运行的任何处理程序 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" } ``` 在你的控制器结构体中持久化数据(在请求之间共享数据),通过定义依赖的服务或者一个`单列` 控制器作用域。 共享控制器之间的依赖关系或在父 MVC 应用程序上注册它们, 并能够在Controller内部的`BeforeActivation`可选事件回调上修改每个控制器的依赖关系, 即, `func(c *MyController) BeforeActivation(b mvc.BeforeActivation) { b.Dependencies().Add/Remove(...) }`。 一个控制器字段访问 `Context`(不需要手动绑定), 即 `Ctx iris.Context` 或者通过一个 方法的输入参数。 即 `func(ctx iris.Context, otherArguments...)`。 控制器结构内部的模型(在Method函数中设置并由View呈现)。你可以从控制器的方法返回模型,或者在请求生命周期中设置一个字段,然后将该字段返回到同一请求生命周期中的另一个方法。 接下来如同你前面所知的一样, mvc 应用有它自己的 `路由` ,它的路由是 `iris/router.Party`类型之一,同时也是标准的 iris api 。 `控制器`可以被注册到任何的 `Party`中,也包括子域, Party 将会如同期望的那样开始和执行处理程序的工作。 可选的 `BeginRequest(ctx)` 函数,将会执行任何初始化在方法执行前,可用于调用中间件或许多方法使用相同的数据集合时。 可选的 `EndRequest(ctx)` 函数, 将会执行任何终止操作在所有的方法执行之后。 继承,递归, 我 [mvc session-controller example](https://github.com/kataras/iris/tree/master/_examples/mvc/session-controller), 有 `Session *sessions.Session` 作为结构体字段, 它被会话管理的 `Start` 方法作为一个动态以来想填充到 MVC 应用: `mvcApp.Register(sessions.New(sessions.Config{Cookie: "iris_session_id"}).Start)`. 通过控制器方法的输入参数访问动态路径参数,无需绑定。 当你使用 Iris 的默认语法从一个控制器中去解析处理程序 , 你需要给方法添加 `By` 后缀, 大写字母是一个新的子路径。 例如: 如果 `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。 可选的, 通过输出参数响应,就如通我们在这章 [Dependency Injection](https://github.com/kataras/iris/wiki/dependency-injection) 内容中所展示的那样。 例如。 ``` 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) ``` `mvc.Result` 是 `hero.Result` 类型的一个别名, 同时它也是一个接口。 ``` type Result interface { // Dispatch 应该发送响应到 context 的响应编写器中。 Dispatch(ctx iris.Context) } ``` ## [示例](https://github.com/kataras/iris/wiki/MVC#example) 此示例等效于 <https://github.com/kataras/iris/blob/master/_examples/hello-world/main.go> 你需要添加代码,这看上去似乎有些得不偿失。但请记住,这个例子并没有使用 iris mvc 的模型, Persistence 或者视图引擎还有 Session 等功能。它仅仅是一个为学习准备的简单例子,你可能永远都不会在你的应用程序中使用如此简单的控制器。 在此示例中,在我的个人笔记本电脑上使用 MVC 模式,在"/hello" 路径上服务每 20MB JSON 的成本是 ~2MB 。 虽然这对于大多数应用程序来说是已经足够,但你还可以选择最适合你的 Iris 功能组合,低级处理程序: 性能更好或者高级控制器: 在大项目中更容易管理和简化代码。 **请仔细阅读注释** ``` package main import ( "github.com/kataras/iris/v12" "github.com/kataras/iris/v12/mvc" "github.com/kataras/iris/v12/middleware/logger" "github.com/kataras/iris/v12/middleware/recover" ) func main() { app := iris.New() // 可选的,增加两个内置处理程序 // 可以从任何 http 相对的恐慌中恢复 // 和将请求记录到终端。 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 服务 // 方法: GET // 资源: http://localhost:8080 func (c *ExampleController) Get() mvc.Result { return mvc.Response{ ContentType: "text/html", Text: "<h1>Welcome</h1>", } } // GetPing 服务 // 方法: GET // 资源: http://localhost:8080/ping func (c *ExampleController) GetPing() string { return "pong" } // GetHello 服务 // 方法: GET // 资源: http://localhost:8080/hello func (c *ExampleController) GetHello() interface{} { return map[string]string{"message": "Hello Iris!"} } // BeforeActivation 只调用一次, 在控制器适应主应用程序前 // 当然也是在主程序运行前。 // 在版本 9 之后,你还可以为特定控制器的方法添加自定义路由。 // 这里你也可以不使用 mvc , 只通过 `ca.Router` 函数使用标准的路由去 // 注册自定义方法的处理程序去做一些事情。 // 并且增加绑定到控制器的字段或者方法函数输入参数上的依赖项。 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 服务 // 方法: GET // 资源: http://localhost:8080/custom_path func (c *ExampleController) CustomHandlerWithoutFollowingTheNamingGuide() string { return "hello from the custom handler without following the naming guide" } // GetUserBy 服务 // 方法: GET // 资源: 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 -> 此控制器的方法名称,该名称应为此路由的处理程序。 b.Handle("GET", "/mypath/{param}", "DoIt", optionalMiddlewareHere...) } // 激活之后, 所有依赖都被设置为 -ed - 所以它们都是只读的。 // 但是任然也可以增加自定义控制器或者简单的标准处理程序。 func (c *ExampleController) AfterActivation(a mvc.AfterActivation) {} */ ``` 在控制其中,每个以 HTTP 方法(`Get`, `Post`, `Put`, `Delete`...)为前缀的 `导出的` 函数,都可作为 HTTP 端点调用。在上面的例子中, ,所有函数都将字符串写入响应。注意每种方法之前的注释。 一个 HTTP 端点是一个Web应用程序中的可定位 URL, 例如`http://localhost:8080/helloworld`,它结合所使用的协议: HTTP,Web服务器的网络位置(包括 TCP 端口): `localhost:8080` 和目标 URI `/helloworld`。 第一条注释指出这是一种[HTTP GET](https://www.w3schools.com/tags/ref_httpmethods.asp) 方法,该方法通过在基本 URL 后面附加 "/helloworld" 来调用。 第三条注释指定一个 [HTTP GET](https://www.w3schools.com/tags/ref_httpmethods.asp) 方法, 该方法通过在 URL 后面附加 "/helloworld/welcome" 来调用。 因为 `By` 关键字,控制器知道如何去处理 `GetBy`上的 "name" 参数 或者 `GetWelcomeBy`上的 "name" 和 "numTimes" 参数,并且构建无样板的动态路由;第三个注释指定一个 [HTTP GET](https://www.w3schools.com/tags/ref_httpmethods.asp) 动态方法,它由任何以"/helloworld/welcome" 开头并且跟随两个路径部分的 URL 调用。第一个部分可以接受任何值并且第二部分只能接受数字,即: "<http://localhost:8080/helloworld/welcome/golang/32719>", 否则,一个 [404 Not Found HTTP 错误](https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.5) 将会被发送到客户端。 > [_examples/mvc](https://github.com/kataras/iris/tree/master/_examples/mvc) 和 [mvc/controller_test.go](https://github.com/kataras/iris/blob/master/mvc/controller_test.go) 文件 用简单的范例解释每个功能, 它们展示了你要如何采用 Iris MVC Binder, Iris MVC Models 和更多其它内容... > 对于 Websocket 控制器,请访问 [Websockets](https://github.com/kataras/iris/wiki/Websockets) 章节。