- Nov 23 2014 -
I have been building the back-end for Endless, a product we make at Studio March, primarily in Go. There have been a few pleasant surprises that the language provides. Here I try to explain an opinionated best practises while coding in Go.
Always see if there is something in the standard library that fits your need before looking else where. In most cases the standard library is just enough.
flag package is seen as parsing arguments from the command line. It can also be used to store configurations your code might need. It also helps serve documentation for all the configurations.
var port int flag.IntVar(&port, "port", 8000, "Specifies the port the server listens to.")
This can either be used as command line arguments or in places which needs default values.
I searched for days to stick to an ORM but finally decided to stick with the vanilla
database/sql package. Many might think this takes us back a step but its simplicity makes up for any drawback. ORMs generally take the least common set of features a database provides. For example you cannot take advantages that Postgres give you with Hstore or Array data types. With the
database/sql you can.
For my needs the
net/http fits well for the few end points of the API. Sometimes I use the Gorilla tool kit when the
http package is not enough. More than a full fledge framework use what you need from the
net/http package or the toolkit.
log package does most of your logging at ease. It is also thread safe which means you can have global
Loggers to do all your logging. Use the
log.Lshortfile flag for debugging purposes. The
testing suite with the
go test command is enough for most test cases.
Go provides tools like
go test which ease up your development, use them effectively.
If you have programmed with Go before you will know that the language designers decided to put a full stop in styling discussions with the
gofmt tool. The tool decides how many tabs, spaces between parenthesis and all the non-essential discussions. But you might have missed the wonderful option which can be used to re-factor your code. The
-r option just does that.
gofmt -r 'pattern -> replacement' <files>
Thus if you want to change a struct Program to Process you would
gofmt -r 'Program -> Process' -w .
If you just want to list the files that contain the changes use a
godoc gofmt to learn more.
The test suite of go has a lot of gems hidden. I use the
-test.run=TestFunction many times. The tool also provides coverage and benchmark analysis. The several tools go provides are useful and enough for most cases. Do read the documentation of these tools. I’m sure you will find some that surprise you.
The Go language internally uses a format which we can follow nearly. Go files that expose a
main package, that is one that builds an executable, reside inside
cmd folder and libraries inside
pkg folder. We can use the
cmd folder to store executables and the root folder(we don’t need to use the
pkg folder to simplify import paths). So if we were creating a web server we could do something like this:
cmd/ endless/ main.go api.go ... models.go db.go ...
This way in our endless/main.go we can use an import path like
os.Getenv("VARIABLE_NAME") to set passwords and other sensitive in your program. This way you avoid pushing passwords in your versioning system.
This is just convenience. Setting it will automatically put binaries in
$HOME/bin and navigating through code can be easier by just following
Follow standards in Effective Go for naming conventions. Try to make your packages read like
The beauty of Go is its simplicity, so try to do the same with your code. Avoid exposing too many variables/structs/functions. Make your API small and simple. This makes it easier to maintain your code.
As I keep coding in Go I learn something new every day. This is definitely not an exhaustive list and some of it is opinionated, take it with a pinch of salt. One good advice is to try the idiomatic way of Go. Almost always the designers have got it right.