MVC

Gerasimos (Makis) Maropoulos在6月11日编辑了本页面·12次修改


MVC - 图1

使用Iris MVC实现代码重用。

通过创建相互独立的组件,开发人员能够在其他应用程序中快速、轻松地重用组件。一个应用程序的相同(或类似)视图可以被重构为具有不同数据的另一个应用程序,因为视图只是处理如何向用户显示数据。

Iris对MVC (Model - View - Controller)架构模式提供了一流的支持,你在Go世界的任何地方都找不到这些东西。您必须导入iris/mvc子包。

  1. import "github.com/kataras/iris/v12/mvc"

Iris web框架支持以最快的速度执行请求数据、模型、持久性数据和绑定。

如果您是后端web开发的新手,请首先阅读有关MVC体系结构模式的文章,wikipedia的那篇文章是一个很好的开始。

注意:在继续之前,请阅读依赖项注入部分。

特性

支持所有HTTP方法,例如,如果想要服务于GET,那么控制器应该有一个名为GET()的函数,您可以在同一个控制器中定义多个方法函数。

通过每个控制器激活前的自定义事件回调,将自定义控制器结构的方法作为具有自定义路径的处理程序(即使是regex参数化路径)。例子:

  1. import (
  2. "github.com/kataras/iris/v12"
  3. "github.com/kataras/iris/v12/mvc"
  4. )
  5. func main() {
  6. app := iris.New()
  7. mvc.Configure(app.Party("/root"), myMVC)
  8. app.Listen(":8080")
  9. }
  10. func myMVC(app *mvc.Application) {
  11. // app.Register(...)
  12. // app.Router.Use/UseGlobal/Done(...)
  13. app.Handle(new(MyController))
  14. }
  15. type MyController struct {}
  16. func (m *MyController) BeforeActivation(b mvc.BeforeActivation) {
  17. // b.Dependencies().Add/Remove
  18. // b.Router().Use/UseGlobal/Done
  19. // and any standard Router API call you already know
  20. // 1-> Method
  21. // 2-> Path
  22. // 3-> The controller's function name to be parsed as handler
  23. // 4-> Any handlers that should run before the MyCustomHandler
  24. b.Handle("GET", "/something/{id:int64}", "MyCustomHandler", anyMiddleware...)
  25. }
  26. // GET: http://localhost:8080/root
  27. func (m *MyController) Get() string {
  28. return "Hey"
  29. }
  30. // GET: http://localhost:8080/root/something/{id:int64}
  31. func (m *MyController) MyCustomHandler(id int64) string {
  32. return "MyCustomHandler says Hey"
  33. }

在控制器结构内的持久性数据(在请求之间共享数据),通过为依赖关系定义服务或拥有一个单例控制器作用域。

在控制器之间共享依赖关系或在父MVC应用程序上注册它们,以及修改每个控制器对控制器内部的BeforeActivation可选事件回调的依赖关系的能力。
例如:

  1. func(c *MyController) BeforeActivation(b mvc.BeforeActivation)
  2. {
  3. b.dependencies().add /Remove(…)
  4. }

以控制器字段的形式访问上下文(不需要手动绑定),即Ctx iris.Context 或通过方法的输入参数,i.e func(ctx iris.Context, otherArguments...).

在控制器结构中建模(在方法函数处设置并由视图呈现)。您可以从控制器的方法返回模型,或者在请求生命周期中设置一个字段,并将该字段返回给同一请求生命周期中的另一个方法。

mvc应用程序有自己的路由器,它是iris/ Router.party的一种类型,标准的iris api。控制器可以注册给任何一方,包括子域,团队的begin和done处理程序如预期的那样工作。

可选的BeginRequest(ctx)函数在方法执行之前执行任何初始化,当许多方法使用相同的数据集合时,调用middlewares很有用。

可选的EndRequest(ctx)函数在任何方法执行后执行任何收尾。

递归继承,例如我们的mvc会话控制器示例,有Session *sessions.Session。会话作为结构字段,由会话管理器填充。

通过控制器方法的输入参数访问动态路径参数,不需要绑定。当您使用Iris的默认语法来解析控制器中的处理程序时,您需要使用By 单词作为方法的后缀,大写是一个新的子路径。例子:

  1. If 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:int64}
  • func(*Controller) PostBy(id int64) - POST:/user/{param:int64}
  1. If mvc.New(app.Party("/profile")).Handle(new(profile.Controller))
  • func(*Controller) GetBy(username string) - GET:/profile/{param:string}
  1. If mvc.New(app.Party("/assets")).Handle(new(file.Controller))
  • func(*Controller) GetByWildcard(path string) - GET:/assets/{param:path}

方法函数接收器支持的类型:int, int64, bool和string。

可选地,通过输出参数响应,就像我们在依赖注入一章中所展示的那样。如。

  1. func(c *ExampleController) Get() string |
  2. (string, string) |
  3. (string, int) |
  4. int |
  5. (int, string) |
  6. (string, error) |
  7. error |
  8. (int, error) |
  9. (any, bool) |
  10. (customStruct, error) |
  11. customStruct |
  12. (customStruct, int) |
  13. (customStruct, string) |
  14. mvc.Result or (mvc.Result, error)

mvc.Result 只是 hero.Result 一种类型别名。

  1. type Result interface {
  2. // Dispatch should sends the response to the context's response writer.
  3. // Dispatch应该将响应发送到上下文的响应编写器。
  4. Dispatch(ctx iris.Context)
  5. }

例子

这个示例相当于一个简单的hello world应用程序。
似乎你需要编写额外的代码不值得,但请记住,这个示例没有使用像模型这样的iris mvc特性,持久性或视图引擎都不会影响会话,它对于学习来说非常简单,你可能永远不会在你的应用中使用简单控制器。

在这个例子中,我们在“/hello”路径上使用MVC服务JSON的成本大约是2MB / 20MB吞吐量,在我的个人笔记本上,大多数应用程序都可以容忍这种情况,但您可以选择最适合您的Iris,低级处理程序:性能或高级控制器:在大型应用程序上更容易维护和更小的代码库。

仔细阅读评论

  1. package main
  2. import (
  3. "github.com/kataras/iris/v12"
  4. "github.com/kataras/iris/v12/mvc"
  5. "github.com/kataras/iris/v12/middleware/logger"
  6. "github.com/kataras/iris/v12/middleware/recover"
  7. )
  8. func main() {
  9. app := iris.New()
  10. // Optionally, add two built'n handlers
  11. // that can recover from any http-relative panics
  12. // and log the requests to the terminal.
  13. //可以选择添加两个构建的n处理程序
  14. //可以从任何相对于http的panics中恢复
  15. //并将请求记录到终端。
  16. app.Use(recover.New())
  17. app.Use(logger.New())
  18. // Serve a controller based on the root Router, "/".
  19. //服务一个控制器基于根路由器,"/"。
  20. mvc.New(app).Handle(new(ExampleController))
  21. // http://localhost:8080
  22. // http://localhost:8080/ping
  23. // http://localhost:8080/hello
  24. // http://localhost:8080/custom_path
  25. app.Listen(":8080")
  26. }
  27. // ExampleController serves the "/", "/ping" and "/hello".
  28. //ExampleController为“/”、“/ping”和“/hello”服务。
  29. type ExampleController struct{}
  30. // Get serves
  31. // Method: GET
  32. // Resource: http://localhost:8080
  33. func (c *ExampleController) Get() mvc.Result {
  34. return mvc.Response{
  35. ContentType: "text/html",
  36. Text: "<h1>Welcome</h1>",
  37. }
  38. }
  39. // GetPing serves
  40. // Method: GET
  41. // Resource: http://localhost:8080/ping
  42. func (c *ExampleController) GetPing() string {
  43. return "pong"
  44. }
  45. // GetHello serves
  46. // Method: GET
  47. // Resource: http://localhost:8080/hello
  48. func (c *ExampleController) GetHello() interface{} {
  49. return map[string]string{"message": "Hello Iris!"}
  50. }
  51. // BeforeActivation called once, before the controller adapted to the main application
  52. // and of course before the server ran.
  53. // After version 9 you can also add custom routes for a specific controller's methods.
  54. // Here you can register custom method's handlers
  55. // use the standard router with `ca.Router` to
  56. // do something that you can do without mvc as well,
  57. // and add dependencies that will be binded to
  58. // a controller's fields or method function's input arguments.
  59. //before activation调用一次,在控制器适应主应用程序之前
  60. //当然,在服务运行之前。
  61. //在版本9之后,您还可以为特定控制器的方法添加自定义路由。
  62. //在这里您可以注册自定义方法的处理程序
  63. //使用带有`ca.Router`路由器的
  64. //做一些不用mvc也能做的事情,
  65. //并添加将绑定到的依赖项
  66. //控制器的字段或方法函数的输入参数。
  67. func (c *ExampleController) BeforeActivation(b mvc.BeforeActivation) {
  68. anyMiddlewareHere := func(ctx iris.Context) {
  69. ctx.Application().Logger().Warnf("Inside /custom_path")
  70. ctx.Next()
  71. }
  72. b.Handle(
  73. "GET",
  74. "/custom_path",
  75. "CustomHandlerWithoutFollowingTheNamingGuide",
  76. anyMiddlewareHere,
  77. )
  78. // or even add a global middleware based on this controller's router,
  79. // which in this example is the root "/":
  80. // b.Router().Use(myMiddleware)
  81. //或者甚至添加一个基于控制器路由器的全局中间件,
  82. //在本例中是根“/”
  83. // b.Router().Use(myMiddleware)
  84. }
  85. // CustomHandlerWithoutFollowingTheNamingGuide serves
  86. // Method: GET
  87. // Resource: http://localhost:8080/custom_path
  88. func (c *ExampleController) CustomHandlerWithoutFollowingTheNamingGuide() string {
  89. return "hello from the custom handler without following the naming guide"
  90. }
  91. // GetUserBy serves
  92. // Method: GET
  93. // Resource: http://localhost:8080/user/{username:string}
  94. // By is a reserved "keyword" to tell the framework that you're going to
  95. // bind path parameters in the function's input arguments, and it also
  96. // helps to have "Get" and "GetBy" in the same controller.
  97. // By是一个保留的“关键字”,它告诉框架您将要
  98. //绑定路径参数在函数的输入参数,它也
  99. //有助于在同一个控制器中拥有“Get”和“GetBy”。
  100. //
  101. // func (c *ExampleController) GetUserBy(username string) mvc.Result {
  102. // return mvc.View{
  103. // Name: "user/username.html",
  104. // Data: username,
  105. // }
  106. // }
  107. /* Can use more than one, the factory will make sure
  108. that the correct http methods are being registered for each route
  109. for this controller, uncomment these if you want:
  110. 可以使用多个,工厂将确保为这个控制器的每个路由注册正确的http方法,如果你想取消注释:
  111. func (c *ExampleController) Post() {}
  112. func (c *ExampleController) Put() {}
  113. func (c *ExampleController) Delete() {}
  114. func (c *ExampleController) Connect() {}
  115. func (c *ExampleController) Head() {}
  116. func (c *ExampleController) Patch() {}
  117. func (c *ExampleController) Options() {}
  118. func (c *ExampleController) Trace() {}
  119. */
  120. /*
  121. func (c *ExampleController) All() {}
  122. // OR
  123. func (c *ExampleController) Any() {}
  124. func (c *ExampleController) BeforeActivation(b mvc.BeforeActivation) {
  125. // 1 -> the HTTP Method
  126. // 2 -> the route's path
  127. // 3 -> this controller's method name that should be handler for that route.
  128. b.Handle("GET", "/mypath/{param}", "DoIt", optionalMiddlewareHere...)
  129. }
  130. // After activation, all dependencies are set-ed - so read only access on them
  131. // but still possible to add custom controller or simple standard handlers.
  132. //激活后,所有依赖项都被设置为只读访问
  133. //但仍然可以添加自定义控制器或简单的标准处理程序。
  134. func (c *ExampleController) AfterActivation(a mvc.AfterActivation) {}
  135. */

在控制器中,每个导出的带有HTTP方法(Get, Post, Put, Delete…)前缀的func都可以作为HTTP端点调用。在上面的示例中,所有funcs都向响应写入一个字符串。注意每个方法前面的注释。

HTTP终端是web应用程序中的可目标URL,例如http://localhost:8080/helloworld,并组合使用的协议:HTTP,web服务器的网络位置(包括TCP端口):localhost:8080和目标URI /helloworld。

第一个注释声明这是一个HTTP GET方法,通过将“/helloworld”附加到基URL来调用。第三条注释指定了一个HTTP GET方法,通过将“/helloworld/welcome”附加到URL来调用该方法。

控制器知道如何处理GetBy上的“name”或GetWelcomeBy上的“name”和“numTimes”,由于采用了By关键字,并构建了无样板的动态路由;第三条注释指定了一个HTTP GET动态方法,该方法由以“/helloworld/welcome”开头并后面跟着两个路径部分的任何URL调用,第一个可以接受任何值,第二个只能接受数字,i,e:“http://localhost:8080/helloworld/welcome/golang/32719”,否则一个404 Not Found HTTP错误将被发送给客户端。

_examples/mvcmvc/controller_test。go文件用简单的范例解释了每个特性,它们展示了你可以如何采用先进的Iris MVC绑定器,Iris MVC模型和更多…

对于websocket控制器,请转到Websockets章节。对于gRPC控制器,请转到gRPC章节。