{"id":34182309,"url":"https://github.com/leonelquinteros/router","last_synced_at":"2026-03-09T23:35:05.893Z","repository":{"id":57600023,"uuid":"95154563","full_name":"leonelquinteros/router","owner":"leonelquinteros","description":"Pure Go's stdlib, idiomatic, simple, net/http compatible, context compatible, http router/mux","archived":false,"fork":false,"pushed_at":"2018-04-30T18:49:58.000Z","size":34,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-12-18T12:53:49.673Z","etag":null,"topics":["context","go","golang","handler","httprouter","mux","router","stdlib"],"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/leonelquinteros.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":"2017-06-22T20:38:17.000Z","updated_at":"2018-08-30T13:26:21.000Z","dependencies_parsed_at":"2022-09-18T09:21:01.897Z","dependency_job_id":null,"html_url":"https://github.com/leonelquinteros/router","commit_stats":null,"previous_names":["bellavista/router"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/leonelquinteros/router","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leonelquinteros%2Frouter","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leonelquinteros%2Frouter/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leonelquinteros%2Frouter/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leonelquinteros%2Frouter/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/leonelquinteros","download_url":"https://codeload.github.com/leonelquinteros/router/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leonelquinteros%2Frouter/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30316772,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-09T20:05:46.299Z","status":"ssl_error","status_checked_at":"2026-03-09T19:57:04.425Z","response_time":61,"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":["context","go","golang","handler","httprouter","mux","router","stdlib"],"created_at":"2025-12-15T14:03:45.419Z","updated_at":"2026-03-09T23:35:05.884Z","avatar_url":"https://github.com/leonelquinteros.png","language":"Go","readme":"[![GoDoc](https://godoc.org/github.com/leonelquinteros/router?status.svg)](https://godoc.org/github.com/leonelquinteros/router)\n[![Version](https://badge.fury.io/gh/leonelquinteros%2Frouter.svg)](https://badge.fury.io/gh/leonelquinteros%2Frouter)\n[![license](https://img.shields.io/github/license/mashape/apistatus.svg)](LICENSE)\n[![Build Status](https://travis-ci.org/leonelquinteros/router.svg?branch=master)](https://travis-ci.org/leonelquinteros/router)\n[![Coverage Status](https://coveralls.io/repos/github/leonelquinteros/router/badge.svg?branch=master)](https://coveralls.io/github/leonelquinteros/router?branch=master)\n[![Go Report Card](https://goreportcard.com/badge/github.com/leonelquinteros/router)](https://goreportcard.com/report/github.com/leonelquinteros/router)\n\n\n# Router\n\n**Pure Go's stdlib, idiomatic, fast, simple, net/http compatible, context compatible, http router/mux**\n\nYour existent http.Handler works with NO CHANGES with this package. And now they can get route parameters!\nThe parameters are stored on the new Context object inside http.Request since Go 1.7. \n\n\n## Requirements\n\n- Go 1.7+\n\n\n## Getting started\n\n```go\npackage main\n\nimport (\n    \"github.com/leonelquinteros/router\"\n    \"net/http\"\n)\n\nfunc sayHello(w http.ResponseWriter, r *http.Request) {\n    w.Write([]byte(\"Hello \" + router.Param(r, \"name\")))\n}\n\nfunc main() {\n    // Create route\n    r := router.New(\"/\")\n    r.Add(\"/hello/:name\", http.HandlerFunc(sayHello))\n    \n    s := \u0026http.Server{\n        Addr:           \":8080\",\n        Handler:        router.Build(r),\n    }\n    \n    s.ListenAndServe()\n}\n```\n\n\n## Handlers\n\nYour handlers are plain simply Go's stdlib [http.Handler](https://golang.org/pkg/net/http/#Handler) objects. \n\n\n```go\n\nimport \"net/http\"\n\ntype MyHandler struct {}\n\nfunc (mh MyHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {\n    w.Write([]byte(\"Hello world!\")\n}\n\n```\n\n\nAnd, if you're used to use the [http.HandleFunc](https://golang.org/pkg/net/http/#HandleFunc) approach, \nyou're still covered by the `net/http` package with [http.HandlerFunc](https://golang.org/pkg/net/http/#HandlerFunc). \n\n```go\n\nimport \"net/http\"\n\nfunc MyHandlerFunc(w http.ResponseWriter, r *http.Request) {\n    w.Write([]byte(\"Hello world!\")\n}\n\nh := http.HandlerFunc(MyHandlerFunc)\n\n```\n\nNo surprises, no changes in the function signature when you want to receive route parameters, nothing. \n\n\n## Routes definition\n\nRoutes are handled by a router object that can group several routes under a single prefix. \nThen, multiple routers can join into a single dispatcher that acts as a replacement for `http.Server.Handler`.\n\n\n```go\n\nimport (\n    \"github.com/leonelquinteros/router\"\n    \"net/http\"\n)\n\nfunc sayHello(w http.ResponseWriter, r *http.Request) {\n    w.Write([]byte(\"Hello \" + router.Param(r, \"name\")))\n}\n\nfunc main() {\n    // Create first router for routes starting at `/v1`\n    r1 := router.New(\"/v1\")\n    r1.Add(\"/hello/:name\", http.HandlerFunc(sayHello))\n    \n    // Create second router for routes starting at `/v2`\n    r2 := router.New(\"/v2\")\n    r2.Add(\"/hello/:name\", http.HandlerFunc(sayHello))\n    \n    // Create http.Server and dispatch both routers\n    s := \u0026http.Server{\n        Addr:           \":8080\",\n        Handler:        router.Build(r1, r2), // router.Build creates the dispatcher object \n    }\n    \n    s.ListenAndServe()\n}\n\n```\n\n\n## Route parameters\n\nSince Go 1.7, the [context](https://golang.org/pkg/context) package is included on the stdlib, and with it, \nthe http.Request object now has a Context included on its definition that allow us to pass context related values (just like our parameters) \nacross the life of our request.\nBella Vista Router uses this new feature to keep it compatible with existent (and future) net/http handlers. \n\nYour routes can hold parameters by defining a route part starting with `:`.\nSo, if you want to receive a parameter called `id` at the end of your `/user` route, you can define and consume as follows\n\n\n```go\n\nimport (\n    \"github.com/leonelquinteros/router\"\n    \"net/http\"\n)\n\nfunc getUser(w http.ResponseWriter, r *http.Request) {\n    id := router.Param(r, \"id\")\n    \n    // Do something with that id\n    // ...\n}\n\nfunc main() {\n    // Create route\n    r := router.New(\"/\")\n    r.Add(\"/user/:id\", http.HandlerFunc(getUser))\n    \n    s := \u0026http.Server{\n        Addr:           \":8080\",\n        Handler:        router.Build(r),\n    }\n    \n    s.ListenAndServe()\n}\n\n```\n\n\n## Middleware\n\nMiddleware type is a function that takes an http.Handler object and returns another http.Handler object to be executed. \nIt has the following signature: \n\n```go\ntype Middleware func(http.Handler) http.Handler\n``` \n\nIt can be used to wrap handlers at handler level, router level and/or dispatcher level so different request flows can be architected:  \n\n```go\n\nimport (\n    \"context\"\n    \"github.com/leonelquinteros/router\"\n    \"net/http\"\n)\n\n// Middleware to set content type\nfunc mContentType(next http.Handler) http.Handler {\n    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {\n        // Set header\n        r.Header().Set(\"Content-Type\", \"text/plain\")\n            \n        // Continue flow\n        next.ServeHTTP(w, r)\n    })\n}\n\n// Handler that says hello\nfunc hSayHello(w http.ResponseWriter, r *http.Request) {\n    r.Write([]byte(\"Hello!\"))\n}\n\nfunc main() {\n    // Create route\n    r := router.New(\"/\")\n    \n    // Use middleware at router level\n    r.Wrap(mContentType)\n    \n    // Route to handler\n    r.Add(\"/hello\", http.HandlerFunc(hSayHello))\n    \n    // Get dispatcher\n    d := router.Build(r)\n    \n    s := \u0026http.Server{\n        Addr:           \":8080\",\n        Handler:        d,\n    }\n    \n    s.ListenAndServe()\n}\n\n```\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fleonelquinteros%2Frouter","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fleonelquinteros%2Frouter","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fleonelquinteros%2Frouter/lists"}