💾 Archived View for dioskouroi.xyz › thread › 25012115 captured on 2020-11-07 at 00:57:37. Gemini links have been rewritten to link to archived content
-=-=-=-=-=-=-
________________________________________________________________________________
The more you get to know Go's stdlib the less and less youll think a web framework is necessary.
Youll find that utilizing http Round Tripper along with the Handler interface in the http library will make middleware easy.
Youll eventually dig into filepath and path methods for extracting path parameters from url paths.
And logging and recovery will be a concept youll need to extend outside of just http and into the rest of your application.
I totally advise new comers to use a web framework, but in the long run, you probably wont want too.
What path to this enlightenment would you recommend to one who has cut his teeth and delivered many projects (over many years) in Rails/Django?
This is a side effect of go’s lack of meta programming to be honest. So much magic that is possible in rails/django/etc is just not possible in golang.
This leads to go web frameworks being sort of semi-hard mountainous turds of code generation. You’ll want to stick to stdlib after sifting through them and deciding they aren’t worth it.
After Django, writing database code manually in Go is not fun at all.
I recently got a DevOps job that mostly involves writing a new backend system in Go completely from scratch.
If this wasn't on the front page of HN I'd have stopped reading here, but it is, so I didn't, then I regretted it.
This article has almost nothing to do with Go in particular. Just...general stuff to follow when writing code. What is it here that talks specific things about "Go" + "in production"?
Haha. Just to attract more clicks
You almost certainly don't need a web framework. Over the long term, it's easy to find yourself boxed in with how opinionated many of them are.
Instead, if you build on the standard library, you can compose your application from there- a good muxer, some standard middleware that are generic http.Handler's, a session library, etc.
So, you chose a good muxer. Now, which of hundreds of logging, cors, sessions, jwt and permissions middlewares work with said mud and with each other best?
Or, and bear with me here, you can outsource those decisions to other folks, and just write your business logic.
Why would you want to serve a 200 with an error message in a JSON response body?
I've seen this pattern before, and one can argue that it is the correct one. Your options are your http status are your application's status, which I think is what most of us are used to.
The other one is http status codes are http status codes. As in the http request was done correctly, but the application code wasn't. More specifically, http layer was executed successfully, but the application layer was not.
I personally like this combo as my "framework":
For configuration management, I've found viper[1] to be quite handy.
[1]:
https://github.com/spf13/viper
For logging libraries, I find TJ's structured logs indispensable:
https://medium.com/@tjholowaychuk/apex-log-e8d9627f4a9a
No need to use Echo..
silently handling panics
That has a bad smell
Especially since caught panics amount to exceptions and most Golang code isn't exception safe. It's a recipe for leaking database connections, deadlocks, etc.
Go error handling is awful, but this isn't a fair.
In go, if you write code like the following:
conn, err := db.Connect() defer conn.Close()
That defer will be run during a panic. Same thing as 'defer mutex.Unlock()'
Yes, like most of go, it's manual and painful and poorly thought out, but most people do follow these patterns, so for the most part go code will safely unwind from a panic.
I wouldn't describe this as good lessons for using Go in production, I would describe this as "opinions I came to after building my first real Go web project."
1. You probably do NOT need a framework
Use the default Go HTTP libraries. For the other functionality that you'll need, use libraries. If you throw in with frameworks like Labstack Echo, you're forever coupled to the incredibly specific and one-note behavior of the framework you choose. The dependencies you choose should be light, with their most attractive aspect being the interfaces they provide. I point most strongly to go-kit as an EXCELLENT set of libraries for writing HTTP services. Their Log package is a small example of what I look for in quality libraries.
2. You NEED a good code structure
You need to be structuring your code, yes. But you should NOT be leaning on the conventional directory structure to give meaning. You will need to read more of other peoples code than you will need to write your own code, and other people will not be following your code structure. Much more useful is to get good tools and practices reading code. Go, unlike other languages (e.g. C#), is meant to be readable and understandable without a heavy IDE there to help resolve elaborate indirection and overloaded imports. If you have the code on your disk and can use Grep, you'll do fine. If you're using an editor which supports language servers like Gopls, you'll be able to fly through the codebases.
3. Pick a DB driver wisely, and the wisest choice for SQL driver is database/sql
SQLx is not database/sql, which is a real problem when most all the ecosystem is built around database/sql. The only real pain point people have with database/sql is the scanning, which is why other people have built libraries to help with this:
https://github.com/kisielk/sqlstruct
Probably just use database/sql.
4. Docker
Most all of this advice is fine.
Basically, I recommend sticking to the more lightweight and more standard implementations, as they have the abstractions you'll need to the long haul. Though if you're just trying to get a thing going ASAP and it has to be Go, do what you gotta do with the code that catches you're fancy.