How I write HTTP services in #golang has changed over the years... here's my current style.
(Please consider sharing this with somebody you know who's learning Go.)
It's a yarn... 🧶
1/13
I make a server type that holds the dependencies.
2/13
all routing goes in routes.go (makes it easy to find stuff, given a URL)
3/13
The handlers are methods on that server type. They can access the dependencies via the receiver.
4/13
My methods aren't actually http.Handler or http.HandlerFunc types, but they do return one when called.
5/13
You can also have handler-specific arguments with all the delicious type safety we get with Go.
It also means you can't get this handler without providing some values for the arguments.
6/13
I tend to use http.HandlerFunc a lot more than http.Handler, because I find the anonymous functions to be so useful.
7/13
I often want to run code before/after my handlers (like for auth, instrumentation, or other common api features.)
8/13
If I'm not using the request/response payload types anywhere else in the case, I put them inside the methods to keep them out of the way...
9/13
... this also means I will sometimes have different types in test code.
I mostly use integration tests for these handlers, so am rarely ever tempted to move the request/response types into package space.
10/13
I use sync.Once to do handler-specific initialisation in a concurrent safe way.
(The pros say we should measure before we optimise, so be sure to check if this is worth doing in your particular case.)
11/13
Since our server type is just a struct, and our handlers are just methods - it makes code quite easy to test.
12/13
Follow for more classic #golang content, if you love content and who doesn't love content? #content
13/13
Share this Scrolly Tale with your friends.
A Scrolly Tale is a new way to read Twitter threads with a more visually immersive experience.
Discover more beautiful Scrolly Tales like this.