{"id":20760389,"url":"https://github.com/vanng822/r2router","last_synced_at":"2025-04-30T05:48:54.727Z","repository":{"id":29152801,"uuid":"32683060","full_name":"vanng822/r2router","owner":"vanng822","description":"A simple router in golang. Suitable for API","archived":false,"fork":false,"pushed_at":"2015-05-23T11:24:32.000Z","size":500,"stargazers_count":9,"open_issues_count":0,"forks_count":0,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-04-30T05:48:47.904Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/vanng822.png","metadata":{"files":{"readme":"README.md","changelog":null,"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":"2015-03-22T16:05:23.000Z","updated_at":"2025-04-05T19:27:12.000Z","dependencies_parsed_at":"2022-09-26T17:41:24.768Z","dependency_job_id":null,"html_url":"https://github.com/vanng822/r2router","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vanng822%2Fr2router","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vanng822%2Fr2router/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vanng822%2Fr2router/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vanng822%2Fr2router/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/vanng822","download_url":"https://codeload.github.com/vanng822/r2router/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251651220,"owners_count":21621702,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":"2024-11-17T10:13:25.424Z","updated_at":"2025-04-30T05:48:54.703Z","avatar_url":"https://github.com/vanng822.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"## r2router\n\nA simple router which supports named parameter. Idea for API or backend without any static content. This package contains 2 router types. Router is for pure routing and Seefor supports middleware stacks.\n\nMiddlewares are divided into 2 groups, one runs before routing and one runs after routing. Before middleware is thought for serving static, logging, recovery from panic and so on. After middleware is thought for pre-processing data before executing endpoint handler. One can do this by using AppSet method on Params. This mean that Before middlewares are always executed, except when a middleware cancels and does not call next(), meanwhile After middlewares are only call if a route is hit. Each After middleware also has a chance to response and stop calling next().\n\nBy default there is no middleware added. See list bellow for suitable middlewares, including recovery which has been moved from this repos.\n\nOne interesting feature this package has is measurement of endpoint performance. The timer measures how long time it takes average for each route. The timer itself is a http.Handler so one can use it to serve these statistics locally (see example/timer.go).\n\nThere is also a route manager for registering all your routes. This can use for setting up endpoints and also use for building urls.\n\n[![GoDoc](https://godoc.org/github.com/vanng822/r2router?status.svg)](https://godoc.org/github.com/vanng822/r2router)\n[![Build Status](https://travis-ci.org/vanng822/r2router.svg?branch=master)](https://travis-ci.org/vanng822/r2router)\n[![Go Walker](http://gowalker.org/api/v1/badge)](https://gowalker.org/github.com/vanng822/r2router) [![](http://gocover.io/_badge/github.com/vanng822/r2router)](http://gocover.io/github.com/vanng822/r2router)\n\n## Example\n\n### Router\n```go\npackage main\n\nimport (\n\t\"github.com/vanng822/r2router\"\n\t\"net/http\"\n)\n\nfunc main() {\n\trouter := r2router.NewRouter()\n\trouter.Get(\"/users/:user\", func(w http.ResponseWriter, r *http.Request, p r2router.Params) {\n\t\tw.Write([]byte(p.Get(\"user\")))\n\t})\n\thttp.ListenAndServe(\":8080\", router)\n}\n```\n\t\nDemo: http://premailer.isgoodness.com/\n\nIf your routes don't contain named params and you have existing http.HandlerFunc then you can wrap as bellow\n\n```go\n\npackage main\n\nimport (\n\t\"fmt\"\n\t\"github.com/vanng822/r2router\"\n\t\"net/http\"\n)\n\n// Wrapper for http.HandlerFunc, similar can be done for http.Handler\nfunc RouteHandlerFunc(next http.HandlerFunc) r2router.HandlerFunc {\n\treturn func(w http.ResponseWriter, r *http.Request, _ r2router.Params) {\n\t\tnext(w, r)\n\t}\n}\n\nfunc main() {\n\tseefor := r2router.NewSeeforRouter()\n\tseefor.Get(\"/hello/world\", RouteHandlerFunc(func(w http.ResponseWriter, r *http.Request) {\n\t\tfmt.Fprint(w, \"Hello world!\")\n\t}))\n\thttp.ListenAndServe(\"127.0.0.1:8080\", seefor)\n}\n```\n\t\n### Measuring endpoint performance using Timer\n\n```go\npackage main\n\nimport (\n\t\"github.com/vanng822/r2router\"\n\t\"net/http\"\n)\n\nfunc main() {\n\trouter := r2router.NewSeeforRouter()\n\trouter.Group(\"/hello\", func(r *r2router.GroupRouter) {\n\t\tr.Get(\"/kitty\", func(w http.ResponseWriter, r *http.Request, _ r2router.Params) {\n\t\t\tw.Write([]byte(\"Mau\"))\n\t\t})\n\n\t\tr.Get(\"/duck\", func(w http.ResponseWriter, r *http.Request, _ r2router.Params) {\n\t\t\tw.Write([]byte(\"Crispy\"))\n\t\t})\n\n\t\tr.Get(\"/:name\", func(w http.ResponseWriter, r *http.Request, p r2router.Params) {\n\t\t\tw.Write([]byte(p.Get(\"name\")))\n\t\t})\n\t})\n\ttimer := router.UseTimer(nil)\n\t\n\tgo http.ListenAndServe(\"127.0.0.1:8080\", router)\n\thttp.ListenAndServe(\"127.0.0.1:8081\", timer)\n}\n```\n\nDemo: http://premailer.isgoodness.com/timers\n\n### Middleware\n\n```go\t\npackage main\n\nimport (\n\t\"fmt\"\n\t\"github.com/vanng822/r2router\"\n\t\"net/http\"\n\t\"log\"\n\t\"time\"\n)\n\nfunc main() {\n\tseefor := r2router.NewSeeforRouter()\n\t// measure time middleware\n\tseefor.Before(func(next http.Handler) http.Handler {\n\t\treturn http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {\n\t\t\tstart := time.Now()\n\t\t\tnext.ServeHTTP(w, r)\n\t\t\tlog.Printf(\"took: %s\", time.Now().Sub(start))\n\t\t})\n\t})\n\t// set label \"say\"\n\tseefor.After(func(next r2router.Handler) r2router.Handler {\n\t\treturn r2router.HandlerFunc(func(w http.ResponseWriter, r *http.Request, p r2router.Params) {\n\t\t\tp.AppSet(\"say\", \"Hello\")\n\t\t\tnext.ServeHTTP(w, r, p)\n\t\t})\n\t})\n\n\tseefor.After(r2router.Wrap(func(w http.ResponseWriter, r *http.Request, p r2router.Params) {\n\t\tp.AppSet(\"goodbye\", \"Bye bye\")\n\t}))\n\n\tseefor.Get(\"/hello/:name\", func(w http.ResponseWriter, r *http.Request, p r2router.Params) {\n\t\tfmt.Fprintf(w, \"%s %s!\\n%s\", p.AppGet(\"say\").(string), p.Get(\"name\"), p.AppGet(\"goodbye\"))\n\t})\n\t\n\thttp.ListenAndServe(\":8080\", seefor)\n}\n```\t\n\nIf you want to add middlewares for a specific route then you should create your own wrapper. This way you will have full control over your middlewares.\nYou could do something like bellow\n\n```go\n\npackage main\n\nimport (\n\t\"fmt\"\n\t\"github.com/vanng822/r2router\"\n\t\"net/http\"\n)\n\n// Your own route middle wrapper\nfunc RouteMiddleware(next r2router.HandlerFunc) r2router.HandlerFunc {\n\treturn func(w http.ResponseWriter, r *http.Request, p r2router.Params) {\n\t\tp.AppSet(\"say\", \"Hello\")\n\t\tnext(w, r, p)\n\t}\n}\n\nfunc main() {\n\tseefor := r2router.NewSeeforRouter()\n\tseefor.Get(\"/hello/:name\", RouteMiddleware(func(w http.ResponseWriter, r *http.Request, p r2router.Params) {\n\t\tfmt.Fprintf(w, \"%s %s!\", p.AppGet(\"say\").(string), p.Get(\"name\"))\n\t}))\n\thttp.ListenAndServe(\"127.0.0.1:8080\", seefor)\n}\n```\n\n\n\n### Route manager\n\n```go\t\npackage main\n\nimport (\n\t\"fmt\"\n\t\"github.com/vanng822/r2router\"\n\t\"net/http\"\n)\n\nfunc main() {\n\tseefor := r2router.NewSeeforRouter()\n\trmanager := r2router.NewRouteManager()\n\t// register and use it at the same time\n\tseefor.Get(rmanager.Add(\"hello::name\", \"/hello/:name\"), func(w http.ResponseWriter, r *http.Request, p r2router.Params) {\n\t\tfmt.Fprintf(w, \"Hello %s!\", p.Get(\"name\"))\n\t})\n\n\t// Or register first elsewhere and get it later\n\trmanager.Add(\"redirect::name\", \"/redirect/:name\")\n\n\tseefor.Get(rmanager.PathFor(\"redirect::name\"), func(w http.ResponseWriter, r *http.Request, p r2router.Params) {\n\t\t// Building url for routename \"hello::name\" and redirect\n\t\thttp.Redirect(w, r, rmanager.UrlFor(\"hello::name\", r2router.P{\"name\": []string{p.Get(\"name\")}}), http.StatusFound)\n\t})\n\n\thttp.ListenAndServe(\"127.0.0.1:8080\", seefor)\n}\n```\t\n\n## Middlewares \u0026 Recommended packages\n\n### Middlewares\n\nPanic recovery https://github.com/vanng822/recovery\n\nAccess log https://github.com/vanng822/accesslog\n\nBasic auth https://github.com/goji/httpauth\n\nCORS https://github.com/rs/cors\n\nQuick security wins https://github.com/unrolled/secure\n\nHMAC authentication https://github.com/auroratechnologies/vangoh\n\nStatic content https://github.com/hypebeast/gojistatic\n\n### Generic packages\n\nRendering https://github.com/unrolled/render\n\nSession https://github.com/gorilla/sessions\n\nHTTP request data binding \u0026 validation https://github.com/mholt/binding\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvanng822%2Fr2router","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvanng822%2Fr2router","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvanng822%2Fr2router/lists"}