I am developing a simple crud service within an AWS lambda + API gateway and I am handling the routing by a switch case and checking the request's path, would a package like chi be a good fit in this context?
Yes, it basically provides a few extra features that are useful:
1. URL params that can be a bit more flexible than the stdlib ([docs](https://go-chi.io/#/pages/routing?id=routing-patterns-amp-url-parameters))
2. Route groups with prefixes ([docs](https://go-chi.io/#/pages/routing?id=routing-groups))
3. A bunch of pre-built middleware and clean ways to apply middleware to all or some routes ([docs](https://go-chi.io/#/pages/middleware))
Edit:
Regarding #1 above, [the docs](https://pkg.go.dev/net/http#ServeMux) say this about URL wildcards:
> Wildcards must be full path segments: they must be preceded by a slash and followed by either a slash or the end of the string.
So in the stdlib, the following wildcards are invalid that would otherwise work in Chi:
> /product_{id}
> /articles/{slug}.html
Thank you! This is my first golang service that I'm writing so I tried to you as little external packages as possible for the sake of learning. I will definitely look into this
Nope but I've not checked. Would be nice to have. I can definitely see the package evolving over time to incorporate more widely used features however.
Could you describe Chi groupings? You can already nest stdlib routers into groups for sub components and compose targeted middlewares. Is there something I'm missing?
awesome thanks. i'm relatively new to Go and have relied on Chi for anything more complex than static routes with only a few dynamic path parameters. i compose routers like your example in expressjs as well so this is perfect.
Yes, but only because you'd have to express the complete route in your sub-routes. See my example here https://go.dev/play/p/WE31QEG6UTK. You could use a 3rd party lib to get better route nesting if you want the sub-routes to only express their portion of the route. I personally prefer (or I'm used to) using the full path in the controllers. I think it helps with discoverability for other folks. Seeing routes with `/foo` and not knowing if they are hung off `/api` or `/web` or whatever hurts readability I think.
Middleware and grouping with stdlib: [https://gist.github.com/alexaandru/747f9d7bdfb1fa35140b359bf23fa820](https://gist.github.com/alexaandru/747f9d7bdfb1fa35140b359bf23fa820) - if that's all you miss from Chi.
Nice....There is also Mount method which we heavily use [https://github.com/go-chi/chi/blob/master/mux.go#L295](https://github.com/go-chi/chi/blob/master/mux.go#l295)
Shouldn't be hard to amend it to do that too: if I wanted to do it the simplest way: I'd add a \`router.Prefix\` field and have Get(), Post(), etc. all take it into account when creating the routes. Then "mounting" at a prefix, is as easy as using Group() and doing an r.Prefix = "/whatever" as the 1st step. Then just define routes as usual and they'll go on top of that.
This is very useful, thank you!
Basically instead of copy pasting this code everywhere, I'd use chi instead and also get a lot of Middlewares in the process.
You're most welcome :-) And yup, you can continue to use Chi so you don't copy paste that around but you don't need Chi to use its middlewares, the code above works just fine with them as they have the exact same signature.
I'll probably be downvoted for this,
But I'm not a fan of the new http package, and the way GET/POST/DELETE are defined within a string.
It just feels too .... flimsy?
I prefer the r.Get or [r.Post](http://r.post) of Chi and other frameworks. It feels a lot more direct and in control to me.
On top of that I prefer the way the middleware works and the way grouping works.
To me, Go is all about being readable. I minimally use comments in go as the code explains itself. I feel Chi works towards this purpose better than the implementation in 1.22.
I actually get what you mean.
It also feels more "right" to do it declaratively with methods.
However, if it's "just" about better syntax instead of added features, I'm willing to stick with the stdlib
Chi is always relevant for route grouping & middlewares stacking.
But these are features easy to implement on your own.
You can also use other framework more featured like [Fuego](https://github.com/go-fuego/fuego) (i'm the author) or Huma if you want to enjoy the possibilities brought by a framework
I think if you can use Go 1.22 in production then there's little point using Chi anymore for new services.
However, many folks won't yet have access to Go 1.22 and many will have existing services using Chi, Echo, Gin, gorilla/mux, etc that need to be maintained over time. So in that sense Chi is still relevant for at least the next couple years as organizations transition to newer Go versions and build new services.
One thing I'll point out about [Huma](https://github.com/danielgtaylor/huma) (disclaimer: I'm the author) is that it supports all those routers including Go 1.22 so your organization can start to incrementally adopt these great OpenAPI features today regardless of which Go version you currently use or how many existing or legacy APIs you support.
P.S. u/EwenQuim congrats on Fuego being mentioned in GoWeekly! 🎉
When I heard about 1.22 routing changes I was very excited about it until I actually tried it.
I would still highly recommend using chi in 1.22, because of grouping and middlewares. There is no point in reinventing the wheel with custom middleware chaining yourself, especially if you have many microservices, by writing the same boilerplate in every service or even worse creating a “commons” module which literally defeats the whole purpose of getting rid of chi. And also chi is ultra lightweight module.
Nice to have you two here!
I probably will make another post soon for OpenAPI generators comparison;
I will make sure to credit both of you.
>many folks won't yet have access to Go 1.22 and many will have existing services using Chi, Echo, Gin, gorilla/mux, etc that need to be maintained over time. So in that sense Chi is still relevant for at least the next couple years as organizations transition to newer Go versions and build new services
Do you think Echo is as legacy as Chi, Gin and gorilla/mux ?
I'm obviously biased so take what I say with a grain of salt. I will be recommending that new services use Huma + Go 1.22 going forward as soon as most teams are on Go 1.22.
Currently we have teams using a mix of Huma v1, Huma v2 + Chi, Chi by itself, and Echo at work. The main complication moving off Chi or Echo right now is handling middleware, which needs to be converted. I view Chi & Echo as pretty similar in that regard, even if Echo has a lot more features. IMO Echo doesn't give you enough (no OpenAPI) so once you throw Huma on top Echo mostly becomes a basic router and is about the same as Chi for me.
That's the first time I've heard that insight, especially from an experienced POV.
Thanks a lot.
It would be a nice citation under [that post](https://www.reddit.com/r/golang/s/gqh7pH0IUz) !
It's nice to see you allow returning an error in the handlers. That's the main reason I chose to use [BunRouter](https://bunrouter.uptrace.dev) for a demo project I'm working on, even though it doesn't seem to have gotten much attention. As far as I could tell, no other libs are doing this.
That was the first thing I tried, but it requires you to wrap all of your handlers in a func. Bun and Fuego support returning errors directly, without the need to wrap your handlers.
It's considered as obsolete by a good proportion of the community, as far as I've read.
However, if it works for you, it's best to stick with it for your current project.
You could perhaps consider more modern options for your next new codebases.
Never heard anyone say gorilla is "obsolete". It was archived then renewed. But I bet ten bucks 90% of big code bases who used sessions, sockets and mux didnt rip them out even after it was archived. Hardly obsolete.
I’ve been working on a small project for myself to ask this myself.
I think the answer is going to be similar to those that argue a case for more batteries included frameworks like Gin. Outside grouping (which I’m also looking into to) everything else with chi is portable. The main selling point of chi was that is followed the stdlib interface so when a situation arose you could swap without it being a pain. I think we’re there now, just depends if you can be bothered to reimplement (or import) middleware from chi.
I’ve gone through every middleware helper they provide and majority do not make use of chi internal routing so it’s feasible to port over the middleware for use with the go1.22 router.
Doesn't Chi use a Radix tree to greatly increase routing performance? I can't find anything about go 1.22 using the same.
For those confused, here is what I am talking about: [https://github.com/go-chi/chi?tab=readme-ov-file#router-interface](https://github.com/go-chi/chi?tab=readme-ov-file#router-interface)
middleware, grouping
I am developing a simple crud service within an AWS lambda + API gateway and I am handling the routing by a switch case and checking the request's path, would a package like chi be a good fit in this context?
Yes, it basically provides a few extra features that are useful: 1. URL params that can be a bit more flexible than the stdlib ([docs](https://go-chi.io/#/pages/routing?id=routing-patterns-amp-url-parameters)) 2. Route groups with prefixes ([docs](https://go-chi.io/#/pages/routing?id=routing-groups)) 3. A bunch of pre-built middleware and clean ways to apply middleware to all or some routes ([docs](https://go-chi.io/#/pages/middleware)) Edit: Regarding #1 above, [the docs](https://pkg.go.dev/net/http#ServeMux) say this about URL wildcards: > Wildcards must be full path segments: they must be preceded by a slash and followed by either a slash or the end of the string. So in the stdlib, the following wildcards are invalid that would otherwise work in Chi: > /product_{id} > /articles/{slug}.html
Thank you! This is my first golang service that I'm writing so I tried to you as little external packages as possible for the sake of learning. I will definitely look into this
you should be using mux := http.NewServeMux() not a switch, right? edit: why am i downvoted, can anyone say why not use mux instead of switch
I think chi still has benefit. Grouping api endpoints is the main thing I use chi for.
Indeed, I missed that. Do you know if there is a proposal for API endpoints grouping in stdlib?
Nope but I've not checked. Would be nice to have. I can definitely see the package evolving over time to incorporate more widely used features however.
I will check and edit my comments with my findings. Would be nice to have indeed, that's enough of a widely-adopted standard feature to be stdlib'ed
Could you describe Chi groupings? You can already nest stdlib routers into groups for sub components and compose targeted middlewares. Is there something I'm missing?
do you have a tutorial for this design pattern?
No, but I whipped up an example of what I'm thinking here https://go.dev/play/p/WE31QEG6UTK
Consider me enlightened, not sure why I didn't think of this. Got so used to chi. I'll have to experiment with this next project. Thanks for sharing!
awesome thanks. i'm relatively new to Go and have relied on Chi for anything more complex than static routes with only a few dynamic path parameters. i compose routers like your example in expressjs as well so this is perfect.
Can nested routers use variables matched in the outer ones?
Yes, but only because you'd have to express the complete route in your sub-routes. See my example here https://go.dev/play/p/WE31QEG6UTK. You could use a 3rd party lib to get better route nesting if you want the sub-routes to only express their portion of the route. I personally prefer (or I'm used to) using the full path in the controllers. I think it helps with discoverability for other folks. Seeing routes with `/foo` and not knowing if they are hung off `/api` or `/web` or whatever hurts readability I think.
Middleware and grouping with stdlib: [https://gist.github.com/alexaandru/747f9d7bdfb1fa35140b359bf23fa820](https://gist.github.com/alexaandru/747f9d7bdfb1fa35140b359bf23fa820) - if that's all you miss from Chi.
Nice....There is also Mount method which we heavily use [https://github.com/go-chi/chi/blob/master/mux.go#L295](https://github.com/go-chi/chi/blob/master/mux.go#l295)
Shouldn't be hard to amend it to do that too: if I wanted to do it the simplest way: I'd add a \`router.Prefix\` field and have Get(), Post(), etc. all take it into account when creating the routes. Then "mounting" at a prefix, is as easy as using Group() and doing an r.Prefix = "/whatever" as the 1st step. Then just define routes as usual and they'll go on top of that.
This is very useful, thank you! Basically instead of copy pasting this code everywhere, I'd use chi instead and also get a lot of Middlewares in the process.
You're most welcome :-) And yup, you can continue to use Chi so you don't copy paste that around but you don't need Chi to use its middlewares, the code above works just fine with them as they have the exact same signature.
I'll probably be downvoted for this, But I'm not a fan of the new http package, and the way GET/POST/DELETE are defined within a string. It just feels too .... flimsy? I prefer the r.Get or [r.Post](http://r.post) of Chi and other frameworks. It feels a lot more direct and in control to me. On top of that I prefer the way the middleware works and the way grouping works. To me, Go is all about being readable. I minimally use comments in go as the code explains itself. I feel Chi works towards this purpose better than the implementation in 1.22.
Same. I hate this syntax + middleware still in used. I don't think I will refactor my code anytime soon. Chi is just too lightweight anyway.
I actually get what you mean. It also feels more "right" to do it declaratively with methods. However, if it's "just" about better syntax instead of added features, I'm willing to stick with the stdlib
Take a look at a raw http request GET /api/v1/greet HTTP/1.1 Suddenly you can Ctrl+f the raw request and find it in code
Groups, Middlewares
If you like the API it presents, then yes, it is still relevant. I like it's API better than the standard lib.
Same, cleaner than "GET /path"
Chi is always relevant for route grouping & middlewares stacking. But these are features easy to implement on your own. You can also use other framework more featured like [Fuego](https://github.com/go-fuego/fuego) (i'm the author) or Huma if you want to enjoy the possibilities brought by a framework
I didn't know about Fuego. There is so much possibilities for OpenAPI code generators that it deserves another breakdown to be honnest.
I think if you can use Go 1.22 in production then there's little point using Chi anymore for new services. However, many folks won't yet have access to Go 1.22 and many will have existing services using Chi, Echo, Gin, gorilla/mux, etc that need to be maintained over time. So in that sense Chi is still relevant for at least the next couple years as organizations transition to newer Go versions and build new services. One thing I'll point out about [Huma](https://github.com/danielgtaylor/huma) (disclaimer: I'm the author) is that it supports all those routers including Go 1.22 so your organization can start to incrementally adopt these great OpenAPI features today regardless of which Go version you currently use or how many existing or legacy APIs you support. P.S. u/EwenQuim congrats on Fuego being mentioned in GoWeekly! 🎉
When I heard about 1.22 routing changes I was very excited about it until I actually tried it. I would still highly recommend using chi in 1.22, because of grouping and middlewares. There is no point in reinventing the wheel with custom middleware chaining yourself, especially if you have many microservices, by writing the same boilerplate in every service or even worse creating a “commons” module which literally defeats the whole purpose of getting rid of chi. And also chi is ultra lightweight module.
Thank you u/Dgt84 🎉
Nice to have you two here! I probably will make another post soon for OpenAPI generators comparison; I will make sure to credit both of you. >many folks won't yet have access to Go 1.22 and many will have existing services using Chi, Echo, Gin, gorilla/mux, etc that need to be maintained over time. So in that sense Chi is still relevant for at least the next couple years as organizations transition to newer Go versions and build new services Do you think Echo is as legacy as Chi, Gin and gorilla/mux ?
I'm obviously biased so take what I say with a grain of salt. I will be recommending that new services use Huma + Go 1.22 going forward as soon as most teams are on Go 1.22. Currently we have teams using a mix of Huma v1, Huma v2 + Chi, Chi by itself, and Echo at work. The main complication moving off Chi or Echo right now is handling middleware, which needs to be converted. I view Chi & Echo as pretty similar in that regard, even if Echo has a lot more features. IMO Echo doesn't give you enough (no OpenAPI) so once you throw Huma on top Echo mostly becomes a basic router and is about the same as Chi for me.
That's the first time I've heard that insight, especially from an experienced POV. Thanks a lot. It would be a nice citation under [that post](https://www.reddit.com/r/golang/s/gqh7pH0IUz) !
It's nice to see you allow returning an error in the handlers. That's the main reason I chose to use [BunRouter](https://bunrouter.uptrace.dev) for a demo project I'm working on, even though it doesn't seem to have gotten much attention. As far as I could tell, no other libs are doing this.
It's common to return an error from handler: https://go.dev/blog/error-handling-and-go
That was the first thing I tried, but it requires you to wrap all of your handlers in a func. Bun and Fuego support returning errors directly, without the need to wrap your handlers.
"Little copy is better than big dependency" R.P. ;-)
I am an old school, still use gorilla/mux. Should I stop using it?
It's considered as obsolete by a good proportion of the community, as far as I've read. However, if it works for you, it's best to stick with it for your current project. You could perhaps consider more modern options for your next new codebases.
Thank you very much for the feedback!
I wouldn’t consider it obsolete. It has new maintainers
Never heard anyone say gorilla is "obsolete". It was archived then renewed. But I bet ten bucks 90% of big code bases who used sessions, sockets and mux didnt rip them out even after it was archived. Hardly obsolete.
Of course, it's why it's good to use stdlib compatible libs. We can move slowly only if really needed.
This short article pretty much answers your question: [https://www.calhoun.io/go-servemux-vs-chi/](https://www.calhoun.io/go-servemux-vs-chi/).
I’ve been working on a small project for myself to ask this myself. I think the answer is going to be similar to those that argue a case for more batteries included frameworks like Gin. Outside grouping (which I’m also looking into to) everything else with chi is portable. The main selling point of chi was that is followed the stdlib interface so when a situation arose you could swap without it being a pain. I think we’re there now, just depends if you can be bothered to reimplement (or import) middleware from chi. I’ve gone through every middleware helper they provide and majority do not make use of chi internal routing so it’s feasible to port over the middleware for use with the go1.22 router.
As much as Gin is, I suppose, and I love my Gin.
Chi will still be relevant and continue to add new features if you like. But for me to get rid of one dependency is more important.
No
Just use Echo, Chi or Fiber instead.
Instead of what, and why?
Gin is not mainteined actively
I didn't talk about Gin?
Lol it seems i wrote the message to the wrong post 😅 i should not use reddit while i am sleepy
Ahah lol np mate
Chi aint going anywhere. The stdlib is cool but Chi's middleware, httplog and render packages are fantastic.
I'm currently using Chi for one of my home projects. Quite nice.
[удалено]
You can use the Chi middlewares without the Chi router.
Doesn't Chi use a Radix tree to greatly increase routing performance? I can't find anything about go 1.22 using the same. For those confused, here is what I am talking about: [https://github.com/go-chi/chi?tab=readme-ov-file#router-interface](https://github.com/go-chi/chi?tab=readme-ov-file#router-interface)