Why Go is the Best Choice for Microservices (and When It's Not)
Imagine you are building a shopping mall. Instead of erecting one giant building, you build separate pavilions: a coffee shop, a bookstore, a grocery store. Each works on its own, but together they form a single complex. The elevator breaks somewhere? The bookstore keeps working. The coffee shop runs out of cups? We close only that one, not the entire complex.
This is the microservice architecture. And Go (Golang) is the ideal material for building such "pavilions." Why?
- Fast start: Compilation into a single binary. No JDK, virtual machines, or node_modules.
- Performance: Go runs at the level of C++, but is written like Python.
- Built-in concurrency: Goroutines and channels are a superpower for handling hundreds of requests per second.
- Simplicity: Go is intentionally limited. No generics (until Go 1.18), no inheritance. The code reads like a vacuum cleaner manual — it's immediately clear what each line does.
But there are downsides too. Go is not suitable if you need:
- Heavy class inheritance (it doesn't exist here at all).
- A huge number of ready-made libraries for any task (the ecosystem is poorer than Java or Python).
- Dynamic typing (Go is strictly typed, you'll have to write more boilerplate).
If your project is a high-load API, a backend for a chat, a payment gateway, or a monitoring system — Go is your choice. If you are writing a prototype over the weekend and don't care about speed — take Python.
Stage 1. Packing Your Suitcase: Tools and Project Structure
What to Install
Before writing code, let's set up the environment. You will need:
- Go (version 1.21+). Download from
go.dev. - Docker (for containerization).
- curl or Postman (for testing the API).
- Any IDE: GoLand, VS Code with the Go plugin, Vim. I recommend VS Code — it's free and convenient.
Correct Folder Structure
Let's agree right away: no shortcuts. Here is the standard structure for a microservice in Go:
/user-service├── cmd/│ └── server/│ └── main.go # entry point├── internal/│ ├── handler/ # HTTP handlers│ ├── service/ # business logic│ ├── repository/ # database interaction│ └── model/ # data structures├── pkg/│ └── middleware/ # common utilities├── Dockerfile├── go.mod└── go.sumWhy this way? Go is a language where the folder structure dictates the architecture. cmd/ is the entry point. internal/ is everything that cannot be imported from outside (foolproof protection). pkg/ is what can be shared with other services.
Stage 2. Writing Your First Microservice: Hello, World! 2.0
Let's write a simple HTTP server in Go that will return JSON. This will be our "greeting microservice."
Step 1. Module Initialization
mkdir hello-servicecd hello-servicego mod init github.com/your-username/hello-serviceStep 2. Writing main.go
package main
import ( "encoding/json" "log" "net/http" "time")
// GreetingResponse — response structuretype GreetingResponse struct { Message string `json:"message"` Timestamp string `json:"timestamp"`}
func greetHandler(w http.ResponseWriter, r *http.Request) { // Set headers w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK)
// Create response response := GreetingResponse{ Message: "Hello, microservices!",