文档章节

Martini 极好的 Go WEB 框架

喻恒春
 喻恒春
发布于 2014/01/07 03:51
字数 877
阅读 18781
收藏 68

已知的其他框架看到的是传统OOP的影子, 到处充蚀 Class 风格的 OOP 方法. 而我们知道GoLang中是没有Class的. 笔者也曾努力用Go 的风格做WEB开发, 总感到力不从心. 写出的代码不能完全称之为框架, 到更像一个拷贝源码使用的应用. 要达到灵活需要修改源码. 直到看到了 Martini. 纯 GoLang 风格的框架出现了.

核心Injector

InjectorMartini 的核心. 其代码非常简洁. 功能仅仅是通过反射包, 对函数进行参数类型自动匹配进行调用. 笔者曾经为完成类似的功能写了typeless, 这是一个繁琐的高成本的实验品. Injector 把事情简单化了, Injector 假设函数的参数都具有不同的类型. 在WEB开发中的 HandlerFunc 通常都具有这样的形式. 因此通过反射包可以对参数进行自动的匹配并调用HandlerFunc, 当然事先要把所有可能使用到的参数 Map/MapTo 给 Injector 对象, 这很容易而且是可以预见的.

简洁的路由设计

Martini的路由 router.go 写的非常简洁实用, 可见作者使用正则的功力非常深厚. 举例:

"/wap/:category/pow/**/:id"

匹配: "/wap/Golang/pow/Path1/ToPathN/Foo"

灵活的中间件

这里的中间件泛指应用需求中的流程控制, 预处理, 过滤器, 捕获 panic, 日志等等.这些依然是Injector在背后提供动力.

举例源代码中的 ClassicMartini ,当然你可以按需求模仿一个.

<!-- lang: cpp -->
func Classic() *ClassicMartini {
	r := NewRouter()
	m := New() // 
	m.Use(Logger()) // 启用日志
	m.Use(Recovery()) // 捕获 panic
	m.Use(Static("public")) // 静态文件
	m.Action(r.Handle) // 最后一个其实是执行了默认的路由机制
	return &ClassicMartini{m, r}
}

其中 Recovery() 和 func (r *routeContext) run() 配合的方法非常值得读一下, 一个简单的计数器就完成了.

martini-contrib 中的 web 包展示了如何通过 Martini.Use 接口进行中间件的设计. 加入新的 HandlerFunc 参数类型就是通过 Map 完成的.

假如我们要完成对 Response 流程的控制, 达不到某个条件中断 Use 和 Action 设置的Handler. 那可以简单的通过 Use 加入自己的 Recovery 和判断 Handler 实现

<!-- lang: cpp -->
func Recovery() Handler {
	return func(res http.ResponseWriter, c Context, logger *log.Logger) {
		defer func() {
			if err := recover(); err != nil {
				s, ok := err.(string) // 示意用 string,你可以定义类型
				if ok && s == "dont ServerError" {
			            return
				}
				res.WriteHeader(http.StatusInternalServerError)
				logger.Printf("PANIC: %s\n%s", err, debug.Stack())
			}
		}()
   		c.Next()
	}
}
func MyHandler() Handler {
    return func(req *http.Request) {
        if something {
           panic("dont ServerError")
        }
    }
}
m.Use(Recovery())
m.Use(MyHandler())

甚至

<!-- lang: cpp -->
// 支持 Handlers 返回值输出
m.Get("/", func() string {
  return "hello world" // HTTP 200 : "hello world"
})
// 向 handlers 传递数据库对象
db := &MyDatabase{}
m := martini.Classic()
m.Map(db) // the service will be available to all handlers as *MyDatabase
// ...
m.Run()

变化和自由度非常高. 正如 Martini 介绍的:

Martini is a powerful package for quickly writing modular web applications/services in Golang.

martini是一个极好的web框架,令人惊讶的简单,难以想象的高效。

是的, 这才是真正的 GoLang 风格.

Martini 社区组件

开发者建立了 martini-contrib 组织. 这样的管理方式更开放. 事实上这样符合 Martini Injector 的风格, 组件之间的依赖可以通过 Injector 的 Map/Invoke 机制完成.

© 著作权归作者所有

喻恒春

喻恒春

粉丝 112
博文 31
码字总数 22644
作品 5
郑州
程序员
私信 提问
加载中

评论(16)

喻恒春
喻恒春 博主

引用来自“UlricQin”的评论

http://codegangsta.io/blog/2014/05/19/my-thoughts-on-martini/ 这哥们……
哈, 这哥们很乐于尝试不同的方法, 感觉这哥们没有思想约束. 关于 Martini, 喜欢的和不喜欢的差不多参半. 就像文章说的, Martini 采用非惯用方法. 话说回来用的人多了就惯用了. 而某系惯用方法, 谁又真正统计过到底在代码中占有多大比例呢!
UlricQin
UlricQin
http://codegangsta.io/blog/2014/05/19/my-thoughts-on-martini/ 这哥们……
BuN_Ny
BuN_Ny
“传统OOP”这一点很吸引我,Go从语言层面就已经去除了臃肿的Class金字塔,但是太多的框架受此影响企图复辟。加之我对Express的偏爱,而此框架又受其影响,所以很值得研究。多谢作者提供此资讯。
喻恒春
喻恒春 博主

引用来自“唐阳”的评论

引用来自“喻恒春”的评论

引用来自“唐阳”的评论

根本看不懂的好吗 能不能写点基础的东西

要介绍一个框架,那是一篇博客就能写好的. 不要急嘛. 还有另外两篇.
http://my.oschina.net/achun/blog/192912

http://my.oschina.net/achun/blog/197546

像use acrion我不知道什么意思

Use,Handlers,Action 都是用来设置 Handler 的.区别是 Use 一次设置一个. Handlers 一次设置全部, Action 用来设置最后一个要 Invoke 的函数, 通常是 Router 的入口.

Erasin
Erasin
研究中...
五杀联盟
五杀联盟

引用来自“喻恒春”的评论

引用来自“唐阳”的评论

根本看不懂的好吗 能不能写点基础的东西

要介绍一个框架,那是一篇博客就能写好的. 不要急嘛. 还有另外两篇.
http://my.oschina.net/achun/blog/192912

http://my.oschina.net/achun/blog/197546

像use acrion我不知道什么意思
喻恒春
喻恒春 博主

引用来自“唐阳”的评论

根本看不懂的好吗 能不能写点基础的东西

要介绍一个框架,那是一篇博客就能写好的. 不要急嘛. 还有另外两篇.
http://my.oschina.net/achun/blog/192912

http://my.oschina.net/achun/blog/197546
五杀联盟
五杀联盟
根本看不懂的好吗 能不能写点基础的东西
qinerg
qinerg

引用来自“喻恒春”的评论

@qinerg 另外因为Go不具备真正的OOP. 所以和class风格是没法比较的. 所以我才感觉inject非常nice.
提供了go风格的用法.

嗯,赞同
喻恒春
喻恒春 博主
@qinerg 另外因为Go不具备真正的OOP. 所以和class风格是没法比较的. 所以我才感觉inject非常nice.
提供了go风格的用法.
Martini 组件和实用工具--martini-contrib

martini-contrib 是一个贡献 Martini 的处理程序和实用工具,这个包包括了各种添加到 Martini 上面的组件和一个高级的GO web 框架。

叶秀兰
2014/01/14
504
0
golang web框架对比

golang web框架 martini revel beego golanger goku wk web.go. 好多框架,能否给做个对比?!怎么选?!

CptJason
2015/07/22
4.2K
2
Golang 建立RESTful webservice 接收客户端POST请求发送wav语音文件

首先看下服务器端,服务器端使用martini框架,仅建立一个简单的接收客户端post请求并保存客户端传过来的语音的后台服务: 原文地址:http://liuxp0827.blog.51cto.com/5013343/1412977 packa...

ponpon_
2014/05/17
0
0
Go语言web框架--Seago

Seago是golang实现的简单的web框架,router包来自web.go和martini 功能 支持RESTful 支持Session 支持Cache 支持Middleware...

大蓝妹
2014/05/06
1K
0
cordova-hcp server 报错

Running server Could not create tunnel: Error: panic: runtime error: invalid memory address or nil pointer dereference github.com/inconshreveable/olive/recover.go:40 runtime/asm......

mamie42
2016/10/17
647
0

没有更多内容

加载失败,请刷新页面

加载更多

代理模式之JDK动态代理 — “JDK Dynamic Proxy“

动态代理的原理是什么? 所谓的动态代理,他是一个代理机制,代理机制可以看作是对调用目标的一个包装,这样我们对目标代码的调用不是直接发生的,而是通过代理完成,通过代理可以有效的让调...

code-ortaerc
20分钟前
2
0
学习记录(day05-标签操作、属性绑定、语句控制、数据绑定、事件绑定、案例用户登录)

[TOC] 1.1.1标签操作v-text&v-html v-text:会把data中绑定的数据值原样输出。 v-html:会把data中值输出,且会自动解析html代码 <!--可以将指定的内容显示到标签体中--><标签 v-text=""></......

庭前云落
52分钟前
7
0
VMware vSphere的两种RDM磁盘

在VMware vSphere vCenter中创建虚拟机时,可以添加一种叫RDM的磁盘。 RDM - Raw Device Mapping,原始设备映射,那么,RDM磁盘是不是就可以称作为“原始设备映射磁盘”呢?这也是一种可以热...

大别阿郎
今天
10
0
【AngularJS学习笔记】02 小杂烩及学习总结

本文转载于:专业的前端网站☞【AngularJS学习笔记】02 小杂烩及学习总结 表格示例 <div ng-app="myApp" ng-controller="customersCtrl"> <table> <tr ng-repeat="x in names | orderBy ......

前端老手
昨天
14
0
Linux 内核的五大创新

在科技行业,创新这个词几乎和革命一样到处泛滥,所以很难将那些夸张的东西与真正令人振奋的东西区分开来。Linux内核被称为创新,但它又被称为现代计算中最大的奇迹,一个微观世界中的庞然大...

阮鹏
昨天
18
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部