{"id":22281685,"url":"https://github.com/andrewburian/powermux","last_synced_at":"2025-07-14T03:12:48.678Z","repository":{"id":18713962,"uuid":"84973072","full_name":"AndrewBurian/powermux","owner":"AndrewBurian","description":"Fast and efficient replacement for Go's ServeMux with middleware, path parameters, and no custom context","archived":false,"fork":false,"pushed_at":"2022-05-16T17:37:11.000Z","size":84,"stargazers_count":20,"open_issues_count":7,"forks_count":4,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-04-05T03:24:05.487Z","etag":null,"topics":["golang","http","router"],"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/AndrewBurian.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-03-14T16:38:46.000Z","updated_at":"2023-07-15T00:44:43.000Z","dependencies_parsed_at":"2022-08-09T09:40:21.627Z","dependency_job_id":null,"html_url":"https://github.com/AndrewBurian/powermux","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/AndrewBurian/powermux","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AndrewBurian%2Fpowermux","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AndrewBurian%2Fpowermux/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AndrewBurian%2Fpowermux/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AndrewBurian%2Fpowermux/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/AndrewBurian","download_url":"https://codeload.github.com/AndrewBurian/powermux/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AndrewBurian%2Fpowermux/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":265237376,"owners_count":23732509,"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":["golang","http","router"],"created_at":"2024-12-03T16:20:32.891Z","updated_at":"2025-07-14T03:12:48.624Z","avatar_url":"https://github.com/AndrewBurian.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# PowerMux\n\n[![Build Status](https://travis-ci.org/AndrewBurian/powermux.svg?branch=master)](https://travis-ci.org/AndrewBurian/powermux)\n[![codecov](https://codecov.io/gh/AndrewBurian/powermux/branch/master/graph/badge.svg)](https://codecov.io/gh/AndrewBurian/powermux)\n[![Release](https://img.shields.io/github/release/AndrewBurian/powermux.svg)](https://github.com/AndrewBurian/powermux/releases)\n\n\nA drop-in replacement for Go's `http.ServeMux` with all the missing features\n\nPowerMux stores routes in radix trees for fast route matching and lookup on large numbers of routes.\n\n## Dependencies\n\nPowerMux requires at least Go version 1.8.\n\n## Setting up PowerMux\n\nIn all cases, PowerMux does not support routes with a trailing slash `/` other than the root node.\nRequests to paths that end in a slash are automatically redirected using a permanent redirection.\n\n### Using `http.ServeMux` syntax\n\nYou can use PowerMux exactly as you would use Go's server mux.\n\n```go\n// Golang default\nmux := http.NewServeMux()\nmux.Handle(\"/\", myHandler)\n  \n// PowerMux\nmux := powermux.NewServeMux()\nmux.Handle(\"/\", myHandler)\n```\n\n### Using the Route syntax\n\nPowerMux also has a cleaner way to declare routes, using the `Route` function.\n\nEach call to `Route()` returns a pointer to that particular path on the radix tree, creating it if necessary.\nAt each route, you can add middleware, set handlers, or descend further into the route:\n\n```go\nmux := powermux.NewServeMux()\n \n// Set a GET handler for \"/\"\nmux.Route(\"/\").Get(myHandler)\n \n// Set POST/DELETE handlers for \"/\"\nmux.Route(\"/\").\n    Post(myPostHandler).\n    Delete(myDeleteHandler)\n```\n\nSequential calls to route have the same effect as a single call with a longer path:\n\n```go\nmux.Route(\"/a\").Route(\"/b\").Route(\"/c\") == mux.Route(\"/a/b/c\")\n```\n\nSince Handler methods also return the route, the syntax can also be chained like so:\n\n```go\nmux.Route(\"/\").\n    Get(rootHandler).\n    \n    Route(\"/a\").\n    Get(aGetHandler).\n    Post(aPostHandler).\n    \n    Route(\"/b\").\n    Get(abGetHandler)\n```\n\n## Middleware\n\nPowerMux has support for any kind of middleware that uses the common `func(res, req, next)` syntax.  \nMiddleware handler objects must implement the `ServeHTTPMiddleware` interface.\n\nMiddleware will **always** be executed before any handlers, including default or generated not found handlers.\n\nMiddleware can be added to any route:\n\n```go\nmux.Route(\"/users\").\n    Middleware(authMiddleware).\n    Get(sensitiveInfoHandler)\n    \n// or\nmux.Route(\"/books\").MiddleWare(loggingMiddleware)\nmux.Route(\"/books\").Get(booksHandler)\n```\n\nMiddleware will be run if it's attached to any part of the route above and including the final path:\n\n```go\nmux.Route(\"/\").Middleware(midRoot)\nmux.Route(\"/a\").Middleware(midA)\nmux.Route(\"/a/b\").Middleware(midB)\nmux.Route(\"/c\").Middleware(midC)\n \n// requests to /a/b will run midRoot, midA, midB, \n// then any handlers on Route(\"/a/b\")\n```\n\nMiddleware can also be set up to selectively execute based on the HTTP method of the request.\n\nThe middleware function variants `MiddlewareFor` and `MiddlewareExceptFor` either set middleware to execute on only\nspecified methods, on all methods except the specified ones respectively.\n\n```go\n// don't run this middleware on OPTIONS requests\nmux.Route(\"/a\").MiddlewareExceptFor(ignoreCorsMid, http.MethodOptions)\n```\n\n## Host specific routes\n\nUnlike the Go default multiplexer, host specific routes need to be handled separately. Use the `*Host` variants of\ncommon functions to achieve this.\n```go\nmux.Route(\"/test\")\nmux.RouteHost(\"example.com\", \"/text\")\n\n// request to any host other than example.com will go to the first handler\n```\n\n## Not Found and OPTIONS handlers\n\n`Options` and `NotFound` handlers are treated specially. If one is not found on the Route node requested, \nthe latest one above that node will be used. This allows whole sections of routes to be covered under custom CORS\nresponses or Not Found handlers\n\n## Path Parameters\n\nRoutes may include path parameters, specified with `/:name`:\n\n```go\nmux.Route(\"/users/:id/info\").\n    Get(userInfoHander)\n```\n\nThis will make the variable `id` available to the get handler and any middleware.  \n\nTo retrieve path parameters, use `PathParam()`:\n\n```go\n// called with /users/andrew/info\nfunc ServeHTTP(w http.ResponseWriter, r *http.Request) {\n        id := powermux.PathParam(r, \"id\")\n        // id == \"andrew\"\n}\n```\n\nPath parameters that aren't found return an empty string.  \nPath parameters are unescaped with `url.PathUnescape`.\n\n## Wildcard patterns\nRoutes may be declared with a wildcard indicator `*` at the end. \nThis will match any path that does not have a more specific handler registered.\n\n```go\nmux.Route(\"/static/*\").Get(staticContentHandler)\nmux.Route(\"/static/favicon\").Get(faviconGenerator)\n \n// requests to /static will all be mapped to static content handler\n// EXCEPT for requests to /static/favicon\n```\n\nDeclaring a wildcard route at the same level as a path parameter route will never be executed as the path parameter takes greater precedence.\n\n```go\nmux.Route(\"/users/:id\") // valid\nmux.Route(\"/users/*\")   // never matched\n```\n\nMore routes may be specified after a wildcard, but they will never be executed:\n\n```go\nr1 := mux.Route(\"/users/*\") // valid\nr1.Route(\"/further/paths\")  // never matched\n```\n\n## Route precedence\n\nIf multiple routes are declared that could match a given path, they are selected in this order:\n\n  1. A literal path `/users/andrew/info`\n  2. A path with parameters `/users/:id/info`\n  3. A wildcard path `/users/*`\n\n## Retrieving the original route path\n\nHandlers and Middleware may access the route pattern that was used by powermux to route any particular \nrequest with the `RequestPath` function.\n\n```go\nservemux.Route(\"/users/:id/info\").Get(userHandler)\n...\n// envoked with /users/andrew/info\nfunc ServeHTTP(rw http.ResponseWriter, req *http.Request) {\n        originalPath := powermux.RequestPath(req)\n        \n        originalPath == \"/users/:id/info\"\n        req.URL.Path == \"/users/andrew/info\"\n}\n```\n\n## Handler precedence\n\nWhen multiple handlers are declared on a single route for different methods, they are selected in this order:\n\n  1. An exact method match\n  2. HEAD requests can use GET handlers\n  3. The ANY handler\n  4. A generated Method Not Allowed handler\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fandrewburian%2Fpowermux","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fandrewburian%2Fpowermux","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fandrewburian%2Fpowermux/lists"}