{"id":37182831,"url":"https://github.com/pboyd/negroni","last_synced_at":"2026-01-14T21:05:29.872Z","repository":{"id":57589063,"uuid":"71829952","full_name":"pboyd/negroni","owner":"pboyd","description":"Idiomatic HTTP Middleware for Golang","archived":false,"fork":true,"pushed_at":"2016-10-24T20:40:10.000Z","size":165,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2024-06-20T14:17:45.217Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":"urfave/negroni","license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pboyd.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-10-24T20:35:43.000Z","updated_at":"2016-10-24T20:35:45.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/pboyd/negroni","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/pboyd/negroni","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pboyd%2Fnegroni","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pboyd%2Fnegroni/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pboyd%2Fnegroni/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pboyd%2Fnegroni/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pboyd","download_url":"https://codeload.github.com/pboyd/negroni/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pboyd%2Fnegroni/sbom","scorecard":{"id":724898,"data":{"date":"2025-08-11","repo":{"name":"github.com/pboyd/negroni","commit":"581c61c2d0f592248bec5f05d94a1aee4dc0dfbb"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3,"checks":[{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Code-Review","score":0,"reason":"Found 0/30 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"SAST","score":0,"reason":"no SAST tool detected","details":["Warn: no pull requests merged into dev branch"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}}]},"last_synced_at":"2025-08-22T12:29:31.704Z","repository_id":57589063,"created_at":"2025-08-22T12:29:31.704Z","updated_at":"2025-08-22T12:29:31.704Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28434530,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-14T18:57:19.464Z","status":"ssl_error","status_checked_at":"2026-01-14T18:52:48.501Z","response_time":107,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-01-14T21:05:29.168Z","updated_at":"2026-01-14T21:05:29.856Z","avatar_url":"https://github.com/pboyd.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Negroni\n[![GoDoc](https://godoc.org/github.com/urfave/negroni?status.svg)](http://godoc.org/github.com/urfave/negroni)\n[![Build Status](https://travis-ci.org/urfave/negroni.svg?branch=master)](https://travis-ci.org/urfave/negroni)\n[![codebeat](https://codebeat.co/badges/47d320b1-209e-45e8-bd99-9094bc5111e2)](https://codebeat.co/projects/github-com-urfave-negroni)\n\n**Notice:** This is the library formerly known as\n`github.com/codegangsta/negroni` -- Github will automatically redirect requests\nto this repository, but we recommend updating your references for clarity.\n\nNegroni is an idiomatic approach to web middleware in Go. It is tiny,\nnon-intrusive, and encourages use of `net/http` Handlers.\n\nIf you like the idea of [Martini](https://github.com/go-martini/martini), but\nyou think it contains too much magic, then Negroni is a great fit.\n\nLanguage Translations:\n* [German (de_DE)](translations/README_de_de.md)\n* [Português Brasileiro (pt_BR)](translations/README_pt_br.md)\n* [简体中文 (zh_cn)](translations/README_zh_cn.md)\n* [繁體中文 (zh_tw)](translations/README_zh_tw.md)\n* [日本語 (ja_JP)](translations/README_ja_JP.md)\n\n## Getting Started\n\nAfter installing Go and setting up your\n[GOPATH](http://golang.org/doc/code.html#GOPATH), create your first `.go` file.\nWe'll call it `server.go`.\n\n\u003c!-- { \"interrupt\": true } --\u003e\n``` go\npackage main\n\nimport (\n  \"fmt\"\n  \"net/http\"\n\n  \"github.com/urfave/negroni\"\n)\n\nfunc main() {\n  mux := http.NewServeMux()\n  mux.HandleFunc(\"/\", func(w http.ResponseWriter, req *http.Request) {\n    fmt.Fprintf(w, \"Welcome to the home page!\")\n  })\n\n  n := negroni.Classic() // Includes some default middlewares\n  n.UseHandler(mux)\n\n  http.ListenAndServe(\":3000\", n)\n}\n```\n\nThen install the Negroni package (**NOTE**: \u0026gt;= **go 1.1** is required):\n\n```\ngo get github.com/urfave/negroni\n```\n\nThen run your server:\n\n```\ngo run server.go\n```\n\nYou will now have a Go `net/http` webserver running on `localhost:3000`.\n\n## Is Negroni a Framework?\n\nNegroni is **not** a framework. It is a middleware-focused library that is\ndesigned to work directly with `net/http`.\n\n## Routing?\n\nNegroni is BYOR (Bring your own Router). The Go community already has a number\nof great http routers available, and Negroni tries to play well with all of them\nby fully supporting `net/http`. For instance, integrating with [Gorilla Mux]\nlooks like so:\n\n``` go\nrouter := mux.NewRouter()\nrouter.HandleFunc(\"/\", HomeHandler)\n\nn := negroni.New(Middleware1, Middleware2)\n// Or use a middleware with the Use() function\nn.Use(Middleware3)\n// router goes last\nn.UseHandler(router)\n\nhttp.ListenAndServe(\":3001\", n)\n```\n\n## `negroni.Classic()`\n\n`negroni.Classic()` provides some default middleware that is useful for most\napplications:\n\n* [`negroni.Recovery`](#recovery) - Panic Recovery Middleware.\n* [`negroni.Logger`](#logger) - Request/Response Logger Middleware.\n* [`negroni.Static`](#static) - Static File serving under the \"public\"\n  directory.\n\nThis makes it really easy to get started with some useful features from Negroni.\n\n## Handlers\n\nNegroni provides a bidirectional middleware flow. This is done through the\n`negroni.Handler` interface:\n\n``` go\ntype Handler interface {\n  ServeHTTP(rw http.ResponseWriter, r *http.Request, next http.HandlerFunc)\n}\n```\n\nIf a middleware hasn't already written to the `ResponseWriter`, it should call\nthe next `http.HandlerFunc` in the chain to yield to the next middleware\nhandler.  This can be used for great good:\n\n``` go\nfunc MyMiddleware(rw http.ResponseWriter, r *http.Request, next http.HandlerFunc) {\n  // do some stuff before\n  next(rw, r)\n  // do some stuff after\n}\n```\n\nAnd you can map it to the handler chain with the `Use` function:\n\n``` go\nn := negroni.New()\nn.Use(negroni.HandlerFunc(MyMiddleware))\n```\n\nYou can also map plain old `http.Handler`s:\n\n``` go\nn := negroni.New()\n\nmux := http.NewServeMux()\n// map your routes\n\nn.UseHandler(mux)\n\nhttp.ListenAndServe(\":3000\", n)\n```\n\n## `Run()`\n\nNegroni has a convenience function called `Run`. `Run` takes an addr string\nidentical to [`http.ListenAndServe`](https://godoc.org/net/http#ListenAndServe).\n\n\u003c!-- { \"interrupt\": true } --\u003e\n``` go\npackage main\n\nimport (\n  \"github.com/urfave/negroni\"\n)\n\nfunc main() {\n  n := negroni.Classic()\n  n.Run(\":8080\")\n}\n```\n\nIn general, you will want to use `net/http` methods and pass `negroni` as a\n`Handler`, as this is more flexible, e.g.:\n\n\u003c!-- { \"interrupt\": true } --\u003e\n``` go\npackage main\n\nimport (\n  \"fmt\"\n  \"log\"\n  \"net/http\"\n  \"time\"\n\n  \"github.com/urfave/negroni\"\n)\n\nfunc main() {\n  mux := http.NewServeMux()\n  mux.HandleFunc(\"/\", func(w http.ResponseWriter, req *http.Request) {\n    fmt.Fprintf(w, \"Welcome to the home page!\")\n  })\n\n  n := negroni.Classic() // Includes some default middlewares\n  n.UseHandler(mux)\n\n  s := \u0026http.Server{\n    Addr:           \":8080\",\n    Handler:        n,\n    ReadTimeout:    10 * time.Second,\n    WriteTimeout:   10 * time.Second,\n    MaxHeaderBytes: 1 \u003c\u003c 20,\n  }\n  log.Fatal(s.ListenAndServe())\n}\n```\n\n## Route Specific Middleware\n\nIf you have a route group of routes that need specific middleware to be\nexecuted, you can simply create a new Negroni instance and use it as your route\nhandler.\n\n``` go\nrouter := mux.NewRouter()\nadminRoutes := mux.NewRouter()\n// add admin routes here\n\n// Create a new negroni for the admin middleware\nrouter.PathPrefix(\"/admin\").Handler(negroni.New(\n  Middleware1,\n  Middleware2,\n  negroni.Wrap(adminRoutes),\n))\n```\n\nIf you are using [Gorilla Mux], here is an example using a subrouter:\n\n``` go\nrouter := mux.NewRouter()\nsubRouter := mux.NewRouter().PathPrefix(\"/subpath\").Subrouter().StrictSlash(true)\nsubRouter.HandleFunc(\"/\", someSubpathHandler) // \"/subpath/\"\nsubRouter.HandleFunc(\"/:id\", someSubpathHandler) // \"/subpath/:id\"\n\n// \"/subpath\" is necessary to ensure the subRouter and main router linkup\nrouter.PathPrefix(\"/subpath\").Handler(negroni.New(\n  Middleware1,\n  Middleware2,\n  negroni.Wrap(subRouter),\n))\n```\n\n## Bundled Middleware\n\n### Static\n\nThis middleware will serve files on the filesystem. If the files do not exist,\nit proxies the request to the next middleware. If you want the requests for\nnon-existent files to return a `404 File Not Found` to the user you should look\nat using [http.FileServer](https://golang.org/pkg/net/http/#FileServer) as\na handler.\n\nExample:\n\n\u003c!-- { \"interrupt\": true } --\u003e\n``` go\npackage main\n\nimport (\n  \"fmt\"\n  \"net/http\"\n\n  \"github.com/urfave/negroni\"\n)\n\nfunc main() {\n  mux := http.NewServeMux()\n  mux.HandleFunc(\"/\", func(w http.ResponseWriter, req *http.Request) {\n    fmt.Fprintf(w, \"Welcome to the home page!\")\n  })\n\n  // Example of using a http.FileServer if you want \"server-like\" rather than \"middleware\" behavior\n  // mux.Handle(\"/public\", http.FileServer(http.Dir(\"/home/public\")))\n\n  n := negroni.New()\n  n.Use(negroni.NewStatic(http.Dir(\"/tmp\")))\n  n.UseHandler(mux)\n\n  http.ListenAndServe(\":3002\", n)\n}\n```\n\nWill serve files from the `/tmp` directory first, but proxy calls to the next\nhandler if the request does not match a file on the filesystem.\n\n### Recovery\n\nThis middleware catches `panic`s and responds with a `500` response code. If\nany other middleware has written a response code or body, this middleware will\nfail to properly send a 500 to the client, as the client has already received\nthe HTTP response code. Additionally, an `ErrorHandlerFunc` can be attached\nto report 500's to an error reporting service such as Sentry or Airbrake.\n\nExample:\n\n\u003c!-- { \"interrupt\": true } --\u003e\n``` go\npackage main\n\nimport (\n  \"net/http\"\n\n  \"github.com/urfave/negroni\"\n)\n\nfunc main() {\n  mux := http.NewServeMux()\n  mux.HandleFunc(\"/\", func(w http.ResponseWriter, req *http.Request) {\n    panic(\"oh no\")\n  })\n\n  n := negroni.New()\n  n.Use(negroni.NewRecovery())\n  n.UseHandler(mux)\n\n  http.ListenAndServe(\":3003\", n)\n}\n```\n\nWill return a `500 Internal Server Error` to each request. It will also log the\nstack traces as well as print the stack trace to the requester if `PrintStack`\nis set to `true` (the default).\n\nExample with error handler:\n\n``` go\npackage main\n\nimport (\n  \"net/http\"\n\n  \"github.com/urfave/negroni\"\n)\n\nfunc main() {\n  mux := http.NewServeMux()\n  mux.HandleFunc(\"/\", func(w http.ResponseWriter, req *http.Request) {\n    panic(\"oh no\")\n  })\n\n  n := negroni.New()\n  recovery := negroni.NewRecovery()\n  recovery.ErrorHandlerFunc = reportToSentry\n  n.Use(recovery)\n  n.UseHandler(mux)\n\n  http.ListenAndServe(\":3003\", n)\n}\n\nfunc reportToSentry(error interface{}) {\n    // write code here to report error to Sentry\n}\n```\n\n\n## Logger\n\nThis middleware logs each incoming request and response.\n\nExample:\n\n\u003c!-- { \"interrupt\": true } --\u003e\n``` go\npackage main\n\nimport (\n  \"fmt\"\n  \"net/http\"\n\n  \"github.com/urfave/negroni\"\n)\n\nfunc main() {\n  mux := http.NewServeMux()\n  mux.HandleFunc(\"/\", func(w http.ResponseWriter, req *http.Request) {\n    fmt.Fprintf(w, \"Welcome to the home page!\")\n  })\n\n  n := negroni.New()\n  n.Use(negroni.NewLogger())\n  n.UseHandler(mux)\n\n  http.ListenAndServe(\":3004\", n)\n}\n```\n\nWill print a log similar to:\n\n```\n[negroni] Started GET /\n[negroni] Completed 200 OK in 145.446µs\n```\n\non each request.\n\n## Third Party Middleware\n\nHere is a current list of Negroni compatible middlware. Feel free to put up a PR\nlinking your middleware if you have built one:\n\n| Middleware | Author | Description |\n| -----------|--------|-------------|\n| [binding](https://github.com/mholt/binding) | [Matt Holt](https://github.com/mholt) | Data binding from HTTP requests into structs |\n| [cloudwatch](https://github.com/cvillecsteele/negroni-cloudwatch) | [Colin Steele](https://github.com/cvillecsteele) | AWS cloudwatch metrics middleware |\n| [cors](https://github.com/rs/cors) | [Olivier Poitrey](https://github.com/rs) | [Cross Origin Resource Sharing](http://www.w3.org/TR/cors/) (CORS) support |\n| [csp](https://github.com/awakenetworks/csp) | [Awake Networks](https://github.com/awakenetworks) | [Content Security Policy](https://www.w3.org/TR/CSP2/) (CSP) support |\n| [delay](https://github.com/jeffbmartinez/delay) | [Jeff Martinez](https://github.com/jeffbmartinez) | Add delays/latency to endpoints. Useful when testing effects of high latency |\n| [New Relic Go Agent](https://github.com/yadvendar/negroni-newrelic-go-agent) | [Yadvendar Champawat](https://github.com/yadvendar) | Official [New Relic Go Agent](https://github.com/newrelic/go-agent) (currently in beta)  |\n| [gorelic](https://github.com/jingweno/negroni-gorelic) | [Jingwen Owen Ou](https://github.com/jingweno) | New Relic agent for Go runtime |\n| [Graceful](https://github.com/tylerb/graceful) | [Tyler Bunnell](https://github.com/tylerb) | Graceful HTTP Shutdown |\n| [gzip](https://github.com/phyber/negroni-gzip) | [phyber](https://github.com/phyber) | GZIP response compression |\n| [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|\n| [logrus](https://github.com/meatballhat/negroni-logrus) | [Dan Buch](https://github.com/meatballhat) | Logrus-based logger |\n| [oauth2](https://github.com/goincremental/negroni-oauth2) | [David Bochenski](https://github.com/bochenski) | oAuth2 middleware |\n| [onthefly](https://github.com/xyproto/onthefly) | [Alexander Rødseth](https://github.com/xyproto) | Generate TinySVG, HTML and CSS on the fly |\n| [permissions2](https://github.com/xyproto/permissions2) | [Alexander Rødseth](https://github.com/xyproto) | Cookies, users and permissions |\n| [prometheus](https://github.com/zbindenren/negroni-prometheus) | [Rene Zbinden](https://github.com/zbindenren) | Easily create metrics endpoint for the [prometheus](http://prometheus.io) instrumentation tool |\n| [render](https://github.com/unrolled/render) | [Cory Jacobsen](https://github.com/unrolled) | Render JSON, XML and HTML templates |\n| [RestGate](https://github.com/pjebs/restgate) | [Prasanga Siripala](https://github.com/pjebs) | Secure authentication for REST API endpoints |\n| [secure](https://github.com/unrolled/secure) | [Cory Jacobsen](https://github.com/unrolled) | Middleware that implements a few quick security wins |\n| [sessions](https://github.com/goincremental/negroni-sessions) | [David Bochenski](https://github.com/bochenski) | Session Management |\n| [stats](https://github.com/thoas/stats) | [Florent Messa](https://github.com/thoas) | Store information about your web application (response time, etc.) |\n| [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 authentication middleware |\n| [xrequestid](https://github.com/pilu/xrequestid) | [Andrea Franz](https://github.com/pilu) | Middleware that assigns a random X-Request-Id header to each request |\n| [mgo session](https://github.com/joeljames/nigroni-mgo-session) | [Joel James](https://github.com/joeljames) | Middleware that handles creating and closing mgo sessions per request |\n\n## Examples\n\n[Alexander Rødseth](https://github.com/xyproto) created\n[mooseware](https://github.com/xyproto/mooseware), a skeleton for writing a\nNegroni middleware handler.\n\n## Live code reload?\n\n[gin](https://github.com/codegangsta/gin) and\n[fresh](https://github.com/pilu/fresh) both live reload negroni apps.\n\n## Essential Reading for Beginners of Go \u0026 Negroni\n\n* [Using a Context to pass information from middleware to end handler](http://elithrar.github.io/article/map-string-interface/)\n* [Understanding middleware](https://mattstauffer.co/blog/laravel-5.0-middleware-filter-style)\n\n## About\n\nNegroni is obsessively designed by none other than the [Code\nGangsta](https://codegangsta.io/)\n\n[Gorilla Mux]: https://github.com/gorilla/mux\n[`http.FileSystem`]: https://godoc.org/net/http#FileSystem\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpboyd%2Fnegroni","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpboyd%2Fnegroni","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpboyd%2Fnegroni/lists"}