Golang Tips and Tricks
The following are some basics on GoLang.
How to
- justforfunc: Programming in Go - YouTube
- GitHub - campoy/justforfunc: The repository for the YouTube series JustForFunc
- GitHub - campoy/go-tooling-workshop: A workshop covering all the tools gophers use in their day to day life
- Documentation - The Go Programming Language
- pkg.go.dev - Documentation on most go packages
- Go Docker image
- golang-standards · GitHub - Shows an example project layout and project-templatez
Quick start
Install Go:
brew install go
You may want to use docker which is what build systems will use
docker pull golang:1.15.4 docker run -rm -v "$PWD":/code -w "/code" golang:1.15.4 go build -v
Install Go plugin to your favorite Editor (e.g., go-plus for Atom)
Setup your repo
If a library then it should be in
$GOPATH/src/<url path>
General project layout
GitHub - golang-standards/project-layout: Standard Go Project Layout
Universal files:
README.md
- Every project should have oneLICENSE.md
- Every project should have onerun
- A script to easily build or test the codego.mod
- initialize as a modulego mod init <name>
go.sum
- commit this if it exists.
/cmd/<name>
This is the place for the main
package. It should build into an executable. <name>
should be the name of the command you want to build. You will build it via go build cmd/<name>
.
Not much code should be here. Just a means to load stuff from /internal
, or /pkg
.
/internal
Private code should be here. This is enforced by the compiler
/pkg
Library code that is ok for others to use.
/vendor
(managed)
This directory is (or should be) managed by your dependency manager and not by you directly.
/build
Not universally recommended, but if your build system takes scripts then it should be /build/ci
and then linked to whatever location the build system wants it to actually be. Where possible it is just a thing wrapper around run
.
Tools
go
- The general tool for godevel
- Go debugger- GitHub - tsliwowicz/go-wrk: go-wrk - a HTTP benchmarking tool based in spirit on the excellent wrk tool
- goimports - An improved
fmt
tool that also handls imports
Libraries
- https://awesome-go.com/ - A curated list of awesome Go libraries
- https://threedots.tech/post/list-of-recommended-libraries/ - 22 libraries known to work in production
Command Tools
GitHub - spf13/cobra: A Commander for modern Go CLI interactions
Configuration Loading
Database
Examples:
- concourse/atc/db - Does not use an ORM or Migration library, example of how to do it manually
DB Drivers
- https://golang.org/pkg/database/sql/ - Golang’s built in SQL Library, most have a compatable interface
- https://github.com/lib/pq -
database/sql
Postgres Driver - https://github.com/jackc/pgx - Postgres specific driver as well as
database/sql
compatible driver. The specific driver interface is more performant, but the standard interface is available for use with other libraries. - https://github.com/Masterminds/squirrel - Fluent SQL generation for golang makes queries easier.
DB ORMs
- https://gorm.io - A Rails-type ORM similar to ActiveRecord.
- https://github.com/go-pg/pg - Golang ORM with focus on PostgreSQL features and performance
- https://godoc.org/github.com/Masterminds/structable - Simple Struct to DB mapper / recorder
DB Migrations
- https://github.com/golang-migrate/migrate - Database migrations. CLI and Golang library. This is library agnostic.
- It has a BinData source driver that allows SQL migration files to be loaded directly into binary.
- https://gorm.io - A Rails-type ORM similar to ActiveRecord, with a similar migration style
- WARNING: in practice these style migration are fragile as there is a tight coupling to the record.
Git
https://pkg.go.dev/github.com/go-git/go-git/v5 - A pure Golang implementation of Git
Gerrit
Note
As a Google maintained project all Golang code is maintained in public version of their GitOnBorg system which uses Gerrit as the review system. To contribute to the main golang code base you have to understand Gerrit.
Gerrit is the code review system used by Google’s Public GoLang team.
Changes (cls) are created by pushing to a special branch called refs/for/<target branch>
. This opens the Equivalent of a GitHub PR. With the difference being that in Gerrit a commit is the unit of work, and in GitHub the branch is.
Topics are a way of associating changes across multiple repos. It is interfaced by using the config push.pushOption = topic=<name>
, or doing it via an option during the push: git push ... -o topic=<name>
, or git push origin HEAD:refs/for/main%topic=<name>
.
https://github.com/andygrunwald/go-gerrit - Gerrit API client
Graphs
- https://github.com/dominikbraun/graph - Generic graph data-structure
HTTP
GitHub - justinas/alice: Painless middleware chaining for Go - Allows Middlewares
GitHub - justinas/nosurf: CSRF protection middleware for Go.
HTTP Router / MUX
Logging
- log - The logging package is enough if all you want to do is add a date
Structured Logging
In most cases structured logging is what you want.
slog - slog augments log by adding levels, and fields. It is usually enough.
GitHub - sirupsen/logrus: Structured, pluggable logging for Go. - Dead project as of 2020-11
GitHub - uber-go/zap: Blazing fast, structured, leveled logging in Go.
Merging Objects
GitHub - imdario/mergo: Mergo: merging Go structs and maps since 2013.
Metrics (prometheus)
Parsing
YAML
- https://gopkg.in/yaml.v2 - Built-in yaml.v2
- sigs.k8s.io/yaml - YAML parser from K8s / Helm
- Use this one when YAML and JSON inter-opt is needed.
// Reading unstructured yaml
data := map[string]interface{}{}
bytes, err := yaml.Parse(fileBytes,&data)
if err != nil {
return nil, err
}
Static Files
GitHub - markbates/pkger: Embed static files in Go binaries (replacement for gobuffalo/packr)
Testing
BDD
- https://github.com/onsi/ginkgo - BDD library
- https://github.com/onsi/gomega - Ginkgo’s Preferred Matcher Library
TDD
https://github.com/smartystreets/goconvey - A nicer testing framework, more TDD like