Choosing a Go framework
Every day, or every few days at the least, somebody comes on /r/golang and asks something along the lines of “Which framework is the best?”. I think we should attempt to ask this question, at least in a way that’s easy to understand. You shouldn’t use a framework.
That was perhaps a very succinct answer to a complex question. It’s not that you shouldn’t use a framework ever. As we all know, when we develop software, it has a tendency to evolve to fit common usage patterns and to make development of the same thing, over and over again, faster. It tries to eliminate repetition, as far as that’s possible.
Standard library or stdlib
The Go standard library is of a great quality. You should use it when you can. You would need to familiarize yourself with the
net/http package if you’re writing
API services, and whatever framework you end up using will be built upon that. Importing third-party packages is logical, when they solve a very focused issue which doesn’t
fit into the standard library. An example of this would be packages that generate UUIDs, or JWT handling. Some packages (including web frameworks) build their value on
top of the standard library. A great example of this would be jmoiron/sqlx which builds on
There are significant differences between Go and languages that include a package marketplace. Node has npm, PHP has packagist (composer) and Ruby would have gems. The fact that Go doesn’t have an official package manager (and a central marketplace) has significant implications in terms of the discoverability of packages. There are several package managers available, for example gvt, glide and an official experiment, dep which might be bundled with the go toolchain sometime in the future.
dep is the official experiment, but not yet the official tool. Check out the Roadmap for more on what this means!
In fact, Glide recommends migrating to dep in the official readme. When you start with vendoring, it’s recommended to use dep.
Go package code lives on GitHub, Bitbucket and other repositories, and can even be self-hosted. The most complete list of go packages could be found by searching godoc, which is central hosting for the documentation generated from these packages. It doesn’t provide a package marketplace similar to the mentioned projects from other languages. A notable project that comes closer to what the other package managers use as a package index would be gopkg.in.
Whatever package which you create might not get adopted due to various reasons from quality of code and so on. Certain package authors are more known than others and if you’re looking for something as trivial as a configuration flags package, you’re left with little but good quality choices. This just isn’t possible in related package systems.
Go has a smaller ecosystem, but there are a lot of Go based projects which have terrific adoption, recently go-chi/chi with 2500 stars on GH
and very positive reviews (like sqlx, the chi project builds on the underlying
net/http package). We use it for ErrorHub, and I can’t recommend it enough.
There are several web frameworks available, but as stated above, you should use the stdlib first, so you can figure out what your needs are when moving forward. Using a web framework is completely unnecessary by itself, but when you flesh out requirements, you might be able to make a more informed choice where to migrate from there.
Migrating from other languages
Go doesn’t really have a high entry level. I was programming PHP for something like 15 years before, and migrating to Go was relatively easy. It’s much harder to wrap your head around asynchronous operation of Node, including Promises and yields. If I can suggest two pieces of reading, you should read the interview with Ryan Dahl, the creator of Node and Bob Nystroms critique of asynchronous functions is a must read as well.
That said, I think Node is not the best system to build a massive server web. I would use Go for that. And honestly, that’s the reason why I left Node. It was the realization that: oh, actually, this is not the best server-side system ever.
- Ryan Dahl
The strength of Go
Go is great for providing API endpoints to whatever project you choose to drive your front-end framework. Websockets? No problem. A cluster of Go programs that are talking to each other? Have you heard of Docker, or Kubernetes? Those are systems that are incredibly scalable, and written in Go.
Go is an excellent language to provide back-end logic like interfacing with the database, and expose this logic via HTTP API endpoints. The choice of your front-end stack will ensure that you can consume and render this data for the browser.
You got burned with React? Replace it with VueJS without throwing any Go code out of the window. In other languages you’d have to discipline
yourself to split the application like this, because often you’re not writing a server, but only the scripts that produce the output that will
then run in the browser. Of course, with Go you may use
html/template in the same way, but implementing your front-end with a front-end
framework of choice, will give you this benefit of finding developers that specialize in that framework. Not everybody is comfortable with Go.
You wouldn’t write a web server in bash, would you?
Why should you use Go?
Mainly the selling point for me is that the quality of the standard library, language and libraries is very high. Ruby, Node, PHP and other web-development centered languages usually are single threaded and going beyond that is an add-on instead of a first-class citizen of the language, if even possible. Their memory management is poor (albeit, for at least PHP it improved greatly over the last 15 years), and perhaps most importantly, all of them seem to fall into the scripting languages category. Compiled code will always run faster than whatever you run via an interpreter.
People always reinvent the wheel, not just because they can, but also because they can improve it in some way. This can be done in small increments, like optimizing a specific function that generates a specific output, or it can be done in larger increments like creating a programming language that has concurrency as a first-class citizen.
Other things might not be handled as well (which is why there’s so much drama about generics in Go), but there’s always space for improvement. I’m not excluding the possibility that somebody would just fork Go and provide generics the best way they see fit. People react to their experiences. If your experience is telling you that concurrency is a problem with some XY language, then you’re going to find a way to solve it. Migrating to Go is a good way to do that.
The article has been edited to reflect that Go indeed has package managers, but as of yet none is official and bundled with the go toolchain. The previous article was misleading that it implied that Go doesn’t have a package manager at all. Technically, all the other package managers (at least npm and composer) are add-ons as well.
While I have you here...
It would be great if you buy one of my books:
- Go with Databases
- Advent of Go Microservices
- API Foundations in Go
- 12 Factor Apps with Docker and Go
Want to stay up to date with new posts?