开启掘金成长之旅!这是我参与「掘金日新计划 · 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 非常简单,我们只需要聚焦路由定义、业务逻辑梳理,总体来说分为以下三个步骤
- 初始化
ClassicMartini对象 - 定于处理的路由地址及相关的逻辑代码
- 启动服务
// 初始化
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())