Golang Web 框架 Martini

1,287 阅读3分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第5天,点击查看活动详情

相信用过Gin框架的小伙伴或多或少都听说过Martini这个框架,那么Martini框架究竟是何方神圣,竟然让目前Golang 社区最为流行的框架Gin在项目描述中要提及:“It features a Martini-like API with much better performance -- up to 40 times faster”;事实上,正如其描述一样Gin的Api风格和Martini很像,而Martini的API风格又是参考了Express,前后都是比较优秀的框架,所以Martini也是值得我们研究学习的。

GitHub项目地址:github.com/go-martini/…

安装

和几乎所有的GO模块一样,通过 go mod init 初始化后,使用 go get 拉取 Martini模块

go get github.com/go-martini/martini

快速上手

上手 Martini 非常简单,我们只需要聚焦路由定义、业务逻辑梳理,总体来说分为以下三个步骤

  1. 初始化 ClassicMartini 对象
  2. 定于处理的路由地址及相关的逻辑代码
  3. 启动服务
// 初始化
c := martini.Classic()
// 监听根地址,当访问跟地址时返回 Hello World!
c.Get("/", func() string {
   return "Hello World!"
})
// 启动服务
c.Run()

路由

Martini 支持常见的 HTTP 方法(GET、POST、PUT、DELETE等),同时也为URI参数的截取提供了便利

获取URI中的参数

通过 : 定义的URI能够被 martini.Params 对象捕获,通过该对象能轻松获取URI上的参数

// curl http://localhost:3000/param/get
// response ==> get
c.Get("/param/:name", func(params martini.Params) string {
   return params["name"]
})

路由分组

通过 Group 方法能够对路由进行分组管理,一个分组中的路由会默认加上分组指定的前缀

// curl http://localhost:3000/g/ping
// response ==> pong
c.Group("/g", func(r martini.Router) {
   r.Get("/ping", func() string {
      return "pong"
   })
})

返回值

默认情况下,Martini 支持的返回数据为字符串,如果需要返回XML、JSON这类的数据可以通过自定义 http.ResponseWriter 来实现

字符串

定义路由中的方法时,设置其返回值为 string 则返回的 http 状态码为200,内容为 return 的值,例如:

c.Get("/", func() string {
   return "Hello World!"
})

如果需要返回其他错误码,可以在定义函数返回值的时候加上int类型:

// 访问根地址时,返回字符串 Hello World!,错误码 500
c.Get("/", func() (int, string) {
   return 500, "Hello World!"
})

返回JSON数据

路由中的函数可以传递 ResponseWriter、Request 两个参数,用来自定义返回、获取Request对象,通过map或struct初始化对象后,使用 Marshal 将其对象转化为 []byte ,再通过 Write 方法返回即可:

c.Get("/json", func(w http.ResponseWriter, r *http.Request) {
   m :=  map[string]interface{}{
      "msg": "success",
   }
   b, _ := json.Marshal(m)
   w.Write(b)
})

中间件

Martini 的核心理念为极简主义,所以像 Auth(权限认证)这种较为广泛的中间件也没有定义在核心项目中,框架中只提供了 Logger(日志)、Recovery(异常捕捉)等较为重要的中间件。

可以参考以下格式定义 Martini 的中间件,如果需要经过中间件后程序继续往后执行则需要使用c.Next()方法,否则程序在中间件的逻辑处理完后就直接结束了:

// 自定义中间件
func SayHello() martini.Handler {
   return func(w http.ResponseWriter, r *http.Request, c martini.Context) {
      w.Write([]byte("Hello"))
      c.Next()
   }
}

// 启动中间件
c.Use(SayHello())