We had two input presentations, one about Go in a startup environment at Sciendis and reasons why Go may be a good choice. And one lightning talk about a data web service.
Go in a startup environment
Sciendis develops a React Native application called Wundera with the backend service being written in Go, in a classic cloud setup. Moving from six to two services (user, patient) proved beneficial, reduced code duplication and also lowered the data serialization overhead.
A few points why Go has been attractive:
- easier language with fewer constructs results in less (cognitive) overhead; faster onboarding, maybe less code
- Go compiles to native Code, minimal requirements on deploy target
- Go garbage collector is minimalistic as well (see e.g. Go GC Settings)
- Go is still a fast language
- approachable concurrency
- community agreement over code style (no more code reviews discussion important, yet shallow problems of style)
- the Go approach to evolve abstractions during the development process using structural typing may mirror project evolution better than upfront designs
Interestingly, with Go you learn and use more the language itself (and its standard library) than a specific framework.
A data web service
Notes: A data web service.
- Java is drafting a lightweight concurrency model as an alternative to threads, see: https://openjdk.java.net/jeps/8277131
Drastically reduce the effort of writing, maintaining, and observing high-throughput concurrent applications that make the best use of available hardware through virtual threads, a lightweight user-mode thread implementation with dramatically reduced costs.
What a concurrency unit is depends on your perspective:
This results in the asynchronous style of programming, that not only requires a separate and incompatible set of APIs, but breaks the connection between the logical application unit (transaction) and the platform’s unit (thread), which makes the platform unaware of the application’s logical units.
- For ideas on idiomatic Go, see: Effective Go
- Go has its dark corners too - we are collecting some of them in Go Gotchas
- End-to-end CI pipeline with GitHub actions, goreleaser and ko: https://github.com/embano1/ci-demo-app
- Test options: https://github.com/stretchr/testify, for integration tests test containers can be used (example test suite starting elasticsearch servers to test an indexing tool).
- In general, having your environment wrapped in containers (and a
docker-compose to set them up) is a popular technique
(discussion) VS Code supports
https://code.visualstudio.com/docs/remote/containers especially via a
devcontainers.jsonfile in your repo:
devcontainer.jsonfile in your project tells VS Code how to access (or create) a development container with a well-defined tool and runtime stack.
- Productive Postgres with Go: GopherCon 2020: Johan Brandhorst-Satzkorn - A Journey to Postgres Productivity with Go
- ORM tools seem to be a bit less used with Go, but options are GORM, or also ent
- sqlite is an awesome database, and since it’s a stable platform, all kinds of project develop around or on top of it, like streaming replication, or trough; video recommendation: David Crawshaw SQLite and Go
- For mocking time in tests: https://github.com/benbjohnson/clock
- Domain-driven design is a popular technique, originating from Eric Evans 2003 book Domain Driven Design, with a good summary being: DDD Distilled – we asked, how a DDD and idiomatic Go fits together; in essence DDD is a tool and if you start with a tool (e.g. DDD), you may miss to start with the actual problem, you are trying to solve (that said, tools are great and certainly necessary)
- If projects get bigger, put an
ARCHITECTURE.mdinto the repo, e.g. like this.
- Tabular test strategy to decouple language from domain content (example dealing with JSON document comparisons).
- Test augmentation library for Go: https://pkg.go.dev/gotest.tools/assert; also useful in tests to compare compound values: google/go-cmp
- If you want to test large data structures, snapshot testing may work: save expected output once, then compare against that snapshot afterwards (snapshotting is also usable for frontend, e.g. making sure your screen did not change by comparing a rendering to a previous version in your test suite)
- Writeup on generics in Go: Go Generics - A Quick Overview
- GopherCon 2020: Johan Brandhorst-Satzkorn - A Journey to Postgres Productivity with Go
- GopherCon 2018: Kat Zien - How Do You Structure Your Go Apps
- dotGo 2019 - Kat Zień - Achieving maintainability with hexagonal architecture
- David Crawshaw SQLite and Go
- Channel: https://www.youtube.com/c/MarcelDempers
Join our meetup to get notified of upcoming events!