# Negroni [![GoDoc](https://godoc.org/github.com/codegangsta/negroni?status.svg)](http://godoc.org/github.com/codegangsta/negroni) [![wercker status](https://app.wercker.com/status/13688a4a94b82d84a0b8d038c4965b61/s "wercker status")](https://app.wercker.com/project/bykey/13688a4a94b82d84a0b8d038c4965b61) 在Go语言里,Negroni 是一个很地道的 web 中间件,它是微型,非嵌入式,并鼓励使用原生 `net/http` 处理器的库。 如果你用过并喜欢 [Martini](http://github.com/go-martini/martini) 框架,但又不想框架中有太多魔幻性的特征,那 Negroni 就是你的菜了,相信它非常适合你。 语言翻译: * [Português Brasileiro (pt_BR)](translations/README_pt_br.md) * [简体中文 (zh_CN)](translations/README_zh_cn.md) ## 入门指导 当安装了 Go 语言并设置好了 [GOPATH](http://golang.org/doc/code.html#GOPATH) 后,新建你第一个`.go` 文件,我们叫它 `server.go` 吧。 ~~~ go package main import ( "github.com/codegangsta/negroni" "net/http" "fmt" ) func main() { mux := http.NewServeMux() mux.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) { fmt.Fprintf(w, "Welcome to the home page!") }) n := negroni.Classic() n.UseHandler(mux) n.Run(":3000") } ~~~ 然后安装 Negroni 包(它依赖 **Go 1.1** 或更高的版本): ~~~ go get github.com/codegangsta/negroni ~~~ 然后运行刚建好的 server.go 文件: ~~~ go run server.go ~~~ 这时一个 Go `net/http` Web 服务器就跑在 `localhost:3000` 上,使用浏览器打开 `localhost:3000` 可以看到输出结果。 ## 需要你的贡献 如果你有问题或新想法,请到[邮件群组](https://groups.google.com/forum/#!forum/negroni-users)里反馈,GitHub issues 是专门给提交 bug 报告和 pull 请求用途的,欢迎你的参与。 ## Negroni 是一个框架吗? Negroni **不**是一个框架,它是为了方便使用 `net/http` 而设计的一个库而已。 ## 路由呢? Negroni 没有带路由功能,使用 Negroni 时,需要找一个适合你的路由。不过好在 Go 社区里已经有相当多可用的路由,Negroni 更喜欢和那些完全支持 `net/http` 库的路由组合使用,比如,结合 [Gorilla Mux](http://github.com/gorilla/mux) 使用像这样: ~~~ go router := mux.NewRouter() router.HandleFunc("/", HomeHandler) n := negroni.New(Middleware1, Middleware2) // Or use a middleware with the Use() function n.Use(Middleware3) // router goes last n.UseHandler(router) n.Run(":3000") ~~~ ## `negroni.Classic()` 经典实例 `negroni.Classic()` 提供一些默认的中间件,这些中间件在多数应用都很有用。 * `negroni.Recovery` - 异常(恐慌)恢复中间件 * `negroni.Logging` - 请求 / 响应 log 日志中间件 * `negroni.Static` - 静态文件处理中间件,默认目录在 "public" 下. `negroni.Classic()` 让你一开始就非常容易上手 Negroni ,并使用它那些通用的功能。 ## Handlers (处理器) Negroni 提供双向的中间件机制,这个特征很棒,都是得益于 `negroni.Handler` 这个接口。 ~~~ go type Handler interface { ServeHTTP(rw http.ResponseWriter, r *http.Request, next http.HandlerFunc) } ~~~ 如果一个中间件没有写入 ResponseWriter 响应,它会在中间件链里调用下一个 `http.HandlerFunc` 执行下去, 它可以这么优雅的使用。如下: ~~~ go func MyMiddleware(rw http.ResponseWriter, r *http.Request, next http.HandlerFunc) { // do some stuff before next(rw, r) // do some stuff after } ~~~ 你也可以用 `Use` 函数把这些 `http.Handler` 处理器引进到处理器链上来: ~~~ go n := negroni.New() n.Use(negroni.HandlerFunc(MyMiddleware)) ~~~ 你还可以使用 `http.Handler`(s) 把 `http.Handler` 处理器引进来。 ~~~ go n := negroni.New() mux := http.NewServeMux() // map your routes n.UseHandler(mux) n.Run(":3000") ~~~ ## `Run()` Negroni 提供一个很好用的函数叫 `Run` ,把地址字符串传人该函数,即可实现很地道的 [http.ListenAndServe](http://golang.org/pkg/net/http#ListenAndServe) 函数功能了。 ~~~ go n := negroni.Classic() // ... log.Fatal(http.ListenAndServe(":8080", n)) ~~~ ## 特定路由中间件 如果你需要群组路由功能,需要借助特定的路由中间件完成,做法很简单,只需建立一个新 Negroni 实例,传人路由处理器里即可。 ~~~ go router := mux.NewRouter() adminRoutes := mux.NewRouter() // add admin routes here // Create a new negroni for the admin middleware router.Handle("/admin", negroni.New( Middleware1, Middleware2, negroni.Wrap(adminRoutes), )) ~~~ ## 第三方中间件 以下的兼容 Negroni 的中间件列表,如果你也有兼容 Negroni 的中间件,可以提交到这个列表来交换链接,我们很乐意做这样有益的事情。 | 中间件 | 作者 | 描述 | | -------------|------------|-------------| | [RestGate](https://github.com/pjebs/restgate) | [Prasanga Siripala](https://github.com/pjebs) | REST API 接口的安全认证 | | [Graceful](https://github.com/stretchr/graceful) | [Tyler Bunnell](https://github.com/tylerb) | 优雅关闭 HTTP 的中间件 | | [secure](https://github.com/unrolled/secure) | [Cory Jacobsen](https://github.com/unrolled) | Middleware that implements a few quick security wins | | [JWT Middleware](https://github.com/auth0/go-jwt-middleware) | [Auth0](https://github.com/auth0) | Middleware checks for a JWT on the `Authorization` header on incoming requests and decodes it| | [binding](https://github.com/mholt/binding) | [Matt Holt](https://github.com/mholt) | HTTP 请求数据注入到 structs 实体| | [logrus](https://github.com/meatballhat/negroni-logrus) | [Dan Buch](https://github.com/meatballhat) | 基于 Logrus-based logger 日志 | | [render](https://github.com/unrolled/render) | [Cory Jacobsen](https://github.com/unrolled) | 渲染 JSON, XML and HTML 中间件 | | [gorelic](https://github.com/jingweno/negroni-gorelic) | [Jingwen Owen Ou](https://github.com/jingweno) | New Relic agent for Go runtime | | [gzip](https://github.com/phyber/negroni-gzip) | [phyber](https://github.com/phyber) | 响应流 GZIP 压缩 | | [oauth2](https://github.com/goincremental/negroni-oauth2) | [David Bochenski](https://github.com/bochenski) | oAuth2 中间件 | | [sessions](https://github.com/goincremental/negroni-sessions) | [David Bochenski](https://github.com/bochenski) | Session 会话管理 | | [permissions2](https://github.com/xyproto/permissions2) | [Alexander Rødseth](https://github.com/xyproto) | Cookies, 用户和权限 | | [onthefly](https://github.com/xyproto/onthefly) | [Alexander Rødseth](https://github.com/xyproto) | 快速生成 TinySVG, HTML and CSS 中间件 | | [cors](https://github.com/rs/cors) | [Olivier Poitrey](https://github.com/rs) | [Cross Origin Resource Sharing](http://www.w3.org/TR/cors/) (CORS) support | | [xrequestid](https://github.com/pilu/xrequestid) | [Andrea Franz](https://github.com/pilu) | 给每个请求指定一个随机 X-Request-Id 头的中间件 | | [VanGoH](https://github.com/auroratechnologies/vangoh) | [Taylor Wrobel](https://github.com/twrobel3) | Configurable [AWS-Style](http://docs.aws.amazon.com/AmazonS3/latest/dev/RESTAuthentication.html) 基于 HMAC 鉴权认证的中间件 | | [stats](https://github.com/thoas/stats) | [Florent Messa](https://github.com/thoas) | 检测 web 应用当前运行状态信息 (响应时间等等。) | ## 范例 [Alexander Rødseth](https://github.com/xyproto) 创建的 [mooseware](https://github.com/xyproto/mooseware) 是一个写兼容 Negroni 中间件的处理器骨架的范例。 ## 即时编译 [gin](https://github.com/codegangsta/gin) 和 [fresh](https://github.com/pilu/fresh) 这两个应用是即时编译的 Negroni 工具,推荐用户开发的时候使用。 ## Go & Negroni 初学者必读推荐 * [在中间件中使用上下文把消息传递给后端处理器](http://elithrar.github.io/article/map-string-interface/) * [了解中间件](http://mattstauffer.co/blog/laravel-5.0-middleware-replacing-filters) ## 关于 Negroni 由 [Code Gangsta](http://codegangsta.io/) 主导设计开发完成