
Building a serverless application with Go, Google Cloud Run and Firebase
Welcome to the first article from the series covering how to build business-oriented applications in Go! In this series, we want to show you how to build applications that are easy to develop, maintain, and fun to work with in the long term. This series doesn’t focus too heavily on infrastructure and implementation details. But we need some foundation to build on later.

A complete Terraform setup of a serverless application on Google Cloud Run and Firebase
In the previous post, Robert introduced Wild Workouts, our example serverless application. Every week or two, we release new articles about this project, focusing on creating business-oriented applications in Go. In this post, I continue where Robert left off and describe the infrastructure setup. We picked Google Cloud Platform (GCP) as the provider of all infrastructure parts of the project. We use Cloud Run for running Go services, Firestore as the database, Cloud Build as CI/CD, and Firebase for web hosting and authentication.

Robust gRPC communication on Google Cloud Run (but not only!)
Welcome to the third article in the series on building business-oriented applications in Go! In this series, we show you how to build applications that are easy to develop, maintain, and fun to work with in the long term. In this article, I describe how to build robust internal communication between your services using gRPC. I also cover the extra configuration required to set up authentication and TLS for Cloud Run.

You should not build your own authentication
Welcome to the third and last article covering how to build “Too Modern Go application”. But don’t worry. This doesn’t mean we’re done showing you how to build applications that are easy to develop, maintain, and fun to work with in the long term. It’s actually just the beginning of a bigger series! We intentionally built the current version of the application to make it hard to maintain and develop in the future.

When to avoid DRY in Go
If you’re here for the first time, this post is part of our Business Applications in Go series. Previously, we introduced Wild Workouts, our example application built with modern tools but containing some subtle anti-patterns. We added them on purpose to show common pitfalls and how to avoid them. In this post, we begin refactoring Wild Workouts. Previous articles will give you more context, but reading them isn’t necessary to understand this one.

Introduction to DDD Lite: When microservices in Go are not enough
When I started working in Go, the community did not look favorably on techniques like DDD (Domain-Driven Design) and Clean Architecture. I heard multiple times: “Don’t do Java in Golang!”, “I’ve seen that in Java, please don’t!”. At the time, I already had almost 10 years of experience in PHP and Python. I’d seen too many bad things there. I remember all those “Eight-thousanders” (methods with 8k+ lines of code 😉) and applications that nobody wanted to maintain.

The Repository pattern in Go: a painless way to simplify your service logic
I’ve seen a lot of complicated code in my life. Pretty often, the reason for that complexity was application logic coupled with database logic. Keeping the logic of your application together with your database logic makes your application much more complex, harder to test, and harder to maintain. There is already a proven and simple pattern that solves these issues. This pattern allows you to separate your application logic from database logic.

4 practical principles of high-quality database integration tests in Go
Did you ever hear about a project where changes were tested on customers you don’t like or countries that aren’t profitable? Or even worse: did you work on such a project? It’s not enough to say that it’s unfair and unprofessional. It’s also hard to develop anything new because you’re afraid to make any change in your codebase. In the 2019 HackerRank Developer Skills Report, Professional growth & learning was marked as the most important factor when looking for a new job.

How to implement Clean Architecture in Go (Golang)
The authors of Accelerate dedicate an entire chapter to software architecture and how it affects development performance. One recurring theme is designing applications to be “loosely coupled”. The goal is for your architecture to support the ability of teams to get their work done—from design through to deployment—without requiring high-bandwidth communication between teams. Accelerate Note If you haven’t read Accelerate yet, I highly recommend it.

How to use basic CQRS in Go
You probably know at least one service that: has one big, unmaintainable model that is hard to understand and change, limits parallel work on new features, or can’t scale optimally. But bad things often come in threes. It’s not uncommon to see services with all these problems. What idea comes to mind first for solving these issues? Let’s split it into more microservices!

Combining DDD, CQRS, and Clean Architecture in Go
In the previous articles, we introduced techniques like DDD Lite, CQRS, and Clean (Hexagonal) Architecture. Even when used alone, they are beneficial. But they work best together. Like Power Rangers. Unfortunately, using them together in a real project is not easy. In this article, I will show you how to connect DDD Lite, CQRS, and Clean Architecture in the most pragmatic and efficient way.

Microservices test architecture. Can you sleep well without end-to-end tests?
Do you know the rare feeling when you develop a new application from scratch and can cover all lines with proper tests? I said “rare” because most of the time, you work with software that has a long history, multiple contributors, and a less-than-obvious testing approach. Even if the code uses good patterns, the test suite doesn’t always follow. Some projects have no modern development environment set up, so there are only unit tests for things that are easy to test.

Repository secure by design: how to sleep better without fear of security vulnerabilities
Thanks to tests and code review, you can make your project bug-free. Right? Well… actually, probably not. That would be too easy. 😉 These techniques lower the chance of bugs, but they can’t eliminate them entirely. Does that mean we need to live with the risk of bugs until the end of our lives? Over a year ago, I found a pretty interesting PR in the harbor project.

Running integration tests with docker-compose in Google Cloud Build
This post is a direct follow-up to Microservices test architecture where I introduced new kinds of tests to our example project. Wild Workouts uses Google Cloud Build as its CI/CD platform. It’s configured for continuous deployment, meaning changes land on production as soon as the pipeline passes. Note State of this article in 2026 This article is kept as an archive.
Series
Popular articles
- The Go libraries that never failed us: 22 libraries you need to know
- Safer Enums in Go
- Common Anti-Patterns in Go Web Applications
- How to implement Clean Architecture in Go (Golang)
- The Repository pattern in Go: a painless way to simplify your service logic
- Introduction to DDD Lite: When microservices in Go are not enough
Tags
- go
- golang
- watermill
- ddd
- events
- software-development
- domain-driven design
- event-driven
- clean-architecture
- web-applications
- anti-patterns
- architecture
- ci
- firestore
- cloudrun
- gcloud
- googlecloud
- microservices
- serverless
- testing
- advanced
- backend
- databases
- devops
- firebase
- gitlab
- reactive
- repository
- ai
- basics
- building-business-applications
- building-in-public
- cqrs
- frameworks
- kafka
- mysql
- nats
- pipelines
- scalability
- software-architecture
- transactions
- agents
- amqp
- authentication
- balance
- bounded-context
- c4
- cicd
- code-quality
- code-review
- complexity
- design-patterns
- development-process
- diagrams
- docker
- dry
- e-book
- efficiency
- enums
- event-storming
- gamedev
- generics
- google-cloud
- grpc
- htmx
- intermediate
- iteration
- javascript
- learning
- libraries
- llm
- metrics
- modular-monolith
- monolith
- open-source
- openapi
- over-engineering
- overengineering
- parallelism
- product-engineering
- productivity
- programming-languages
- prometheus
- pull-requests
- python
- rabbitmq
- retrospective
- security
- software-design
- sql
- sse
- startups
- strategic-ddd
- swagger
- terraform
- tips
- unpopular-opinions
- versioning
- work-culture