{"slug": "chi-like-syntactic-sugar-layer-on-top-of-stdlib-http-servemux", "title": "Chi-like syntactic sugar layer on top of stdlib http.ServeMux", "summary": "This code defines a lightweight router in Go that adds a Chi-like syntactic sugar layer on top of the standard library's `http.ServeMux`. It provides method-specific routing (GET, POST, PUT, DELETE, etc.), middleware chaining with `Use()`, and route grouping via `Group()`, while wrapping handlers with middleware in the correct order. The included example demonstrates creating a router with global middleware, grouped routes with additional middleware, and per-route middleware.", "body_md": "chi.go\n\n      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.\n      \nLearn more about bidirectional Unicode characters\n\n \n    Show hidden characters\n\n// Chi-like syntactic sugar layer on top of stdlib http.ServeMux.\n\npackage main\n\nimport (\n\n\t\"net/http\"\n\n\t\"slices\"\n\n)\n\ntype (\n\n\tmiddleware func(http.Handler) http.Handler\n\n\trouter     struct {\n\n\t\t*http.ServeMux\n\n\t\tchain []middleware\n\n\t}\n\n)\n\nfunc NewRouter(mx ...middleware) *router {\n\n\treturn &router{ServeMux: &http.ServeMux{}, chain: mx}\n\n}\n\nfunc (r *router) Use(mx ...middleware) {\n\n\tr.chain = append(r.chain, mx...)\n\n}\n\nfunc (r *router) Group(fn func(r *router)) {\n\n\tfn(&router{ServeMux: r.ServeMux, chain: slices.Clone(r.chain)})\n\n}\n\nfunc (r *router) Get(path string, fn http.HandlerFunc, mx ...middleware) {\n\n\tr.handle(http.MethodGet, path, fn, mx)\n\n}\n\nfunc (r *router) Post(path string, fn http.HandlerFunc, mx ...middleware) {\n\n\tr.handle(http.MethodPost, path, fn, mx)\n\n}\n\nfunc (r *router) Put(path string, fn http.HandlerFunc, mx ...middleware) {\n\n\tr.handle(http.MethodPut, path, fn, mx)\n\n}\n\nfunc (r *router) Delete(path string, fn http.HandlerFunc, mx ...middleware) {\n\n\tr.handle(http.MethodDelete, path, fn, mx)\n\n}\n\nfunc (r *router) Head(path string, fn http.HandlerFunc, mx ...middleware) {\n\n\tr.handle(http.MethodHead, path, fn, mx)\n\n}\n\nfunc (r *router) Options(path string, fn http.HandlerFunc, mx ...middleware) {\n\n\tr.handle(http.MethodOptions, path, fn, mx)\n\n}\n\nfunc (r *router) handle(method, path string, fn http.HandlerFunc, mx []middleware) {\n\n\tr.Handle(method+\" \"+path, r.wrap(fn, mx))\n\n}\n\nfunc (r *router) wrap(fn http.HandlerFunc, mx []middleware) (out http.Handler) {\n\n\tout, mx = http.Handler(fn), append(slices.Clone(r.chain), mx...)\n\n\tslices.Reverse(mx)\n\n\tfor _, m := range mx {\n\n\t\tout = m(out)\n\n\t}\n\n\treturn\n\n}\n\nexample.go\n\n      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.\n      \nLearn more about bidirectional Unicode characters\n\n \n    Show hidden characters\n\npackage main\n\nimport (\n\n\t\"fmt\"\n\n\t\"log\"\n\n\t\"net/http\"\n\n)\n\nfunc mid(i int) middleware {\n\n\treturn func(next http.Handler) http.Handler {\n\n\t\treturn http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {\n\n\t\t\tfmt.Println(\"mid\", i, \"start\")\n\n\t\t\tnext.ServeHTTP(w, r)\n\n\t\t\tfmt.Println(\"mid\", i, \"done\")\n\n\t\t})\n\n\t}\n\n}\n\nfunc someHandler(w http.ResponseWriter, r *http.Request) {\n\n\tfmt.Println(\"[the handler ran here]\")\n\n\tfmt.Fprintln(w, \"Hello world of\", r.URL.Path)\n\n}\n\nfunc main() {\n\n\tr := NewRouter(mid(0))\n\n\tr.Group(func(r *router) {\n\n\t\tr.Use(mid(1), mid(2))\n\n\t\tr.Get(\"/foo\", someHandler)\n\n\t})\n\n\tr.Group(func(r *router) {\n\n\t\tr.Use(mid(3))\n\n\t\tr.Get(\"/bar\", someHandler, mid(4))\n\n\t\tr.Get(\"/baz\", someHandler, mid(5))\n\n\t})\n\n\tr.Post(\"/foobar\", someHandler)\n\n\tlog.Fatal(http.ListenAndServe(\":3000\", r))\n\n}", "url": "https://wpnews.pro/news/chi-like-syntactic-sugar-layer-on-top-of-stdlib-http-servemux", "canonical_source": "https://gist.github.com/alexaandru/747f9d7bdfb1fa35140b359bf23fa820", "published_at": "2024-02-14 16:40:44+00:00", "updated_at": "2026-05-22 18:38:52.396889+00:00", "lang": "en", "topics": ["developer-tools"], "entities": [], "alternates": {"html": "https://wpnews.pro/news/chi-like-syntactic-sugar-layer-on-top-of-stdlib-http-servemux", "markdown": "https://wpnews.pro/news/chi-like-syntactic-sugar-layer-on-top-of-stdlib-http-servemux.md", "text": "https://wpnews.pro/news/chi-like-syntactic-sugar-layer-on-top-of-stdlib-http-servemux.txt", "jsonld": "https://wpnews.pro/news/chi-like-syntactic-sugar-layer-on-top-of-stdlib-http-servemux.jsonld"}}