A production-grade backend system built in Go demonstrating:
- Clean architecture
- gRPC microservice communication
- HTTP API Gateway
- Concurrent worker pool
- Real-time updates via WebSockets
- PostgreSQL persistence
- Interceptors (logging, recovery, request tracing)
- Graceful shutdown
- Context propagation
- Dockerized microservice deployment
This project simulates a real-world backend system architecture commonly used in scalable microservice environments.
Client (HTTP / WebSocket)
│
▼
API Gateway (HTTP :8080)
│
▼
gRPC Order Service (:50051)
│
├── PostgreSQL
└── Worker Pool (5 goroutines)
│
▼
WebSocket Hub (:8081)
│
▼
Client
+---------------------+
| API Gateway |
| (HTTP) |
| :8080 |
+----------+----------+
|
v
+---------------------+
| Order Service |
| gRPC Server |
| :50051 |
| WebSocket :8081 |
+----------+----------+
|
v
+---------------------+
| PostgreSQL |
| :5432 |
+---------------------+
All services run inside a Docker network and communicate using service names.
Example:
api-gateway → order-service:50051
order-service → postgres:5432
| Layer | Technology |
|---|---|
| Language | Go |
| Transport | gRPC |
| API Layer | HTTP (Chi Router) |
| Real-Time | WebSocket (Melody) |
| Concurrency | Goroutines + Channels |
| Database | PostgreSQL |
| Logging | Zap |
| Proto | Protocol Buffers |
| Containerization | Docker + Docker Compose |
order-system/
│
├── cmd/
│ ├── order-service/ # gRPC + WebSocket service
│ │ └── Dockerfile
│ │
│ ├── api-gateway/ # HTTP gateway
│ │ └── Dockerfile
│ │
│ └── main.go # standalone application for manual testing
│
├── internal/
│ ├── config/ # Environment configuration loader
│ ├── db/ # PostgreSQL connection + retry logic
│ ├── order/ # Domain + service + repository
│ ├── worker/ # Worker pool implementation
│ ├── ws/ # WebSocket hub
│ └── interceptor/ # gRPC interceptors
│
├── proto/
│ ├── order.proto
│ ├── order.pb.go
│ └── order_grpc.pb.go
│
├── migrations/ # DB schema migrations
│
├── pkg/
│ └── logger/ # Zap logger setup
│
├── docker-compose.yml # container orchestration
│
├── go.mod
└── go.sum
- Business logic is independent of transport layer.
- Repository pattern isolates database access.
- Services depend on abstractions rather than implementations.
- Transport layers (HTTP/gRPC) simply adapt requests to the service layer.
- Fixed 5 goroutines
- Buffered job queue
- Context-aware processing
- Graceful shutdown support
Order Created
│
▼
Worker Processes Order
│
▼
Order Status Updated in DB
│
▼
WebSocket Hub Publishes Event
│
▼
Subscribed Clients Receive Update
The system can be run in two ways:
- Local Development (manual services)
- Docker Deployment (recommended)
- Go 1.21+
- PostgreSQL
- Docker
- protoc
- protoc-gen-go
- protoc-gen-go-grpc
docker run --name order-postgres \
-e POSTGRES_USER=admin \
-e POSTGRES_PASSWORD=admin123 \
-e POSTGRES_DB=orderdb \
-p 5432:5432 \
-d postgres
migrate -path migrations \
-database "postgres://admin:admin123@localhost:5432/orderdb?sslmode=disable" up
go run cmd/order-service/main.go
Runs on:
gRPC :50051
WebSocket :8081
go run cmd/api-gateway/main.go
Runs on:
HTTP :8080
The entire system can be started with one command using Docker Compose.
This launches:
- PostgreSQL container
- Order Service container
- API Gateway container
All connected through a shared Docker network.
From the project root:
docker compose up --build
Docker will:
- Build Go binaries
- Create containers
- Start PostgreSQL
- Start order-service
- Start API gateway
docker compose down
docker ps
Expected services:
order-postgres
order-service
api-gateway
POST
http://localhost:8080/orders
Body:
{
"user_id": "user-1",
"amount": 100
}GET
http://localhost:8080/orders/{order_id}
- Open Postman
- Create WebSocket request
Connect to:
ws://localhost:8081/ws
Send the Order ID:
"ORDER_ID_HERE"
When the worker processes the order you will receive:
{
"order_id": "...",
"status": "PROCESSED"
}- Logging interceptor
- Panic recovery interceptor
- Request ID tracing
- Database queries use context
- Worker pool supports cancellation
- HTTP requests propagate context to gRPC
- gRPC calls use timeouts
The system safely handles:
- SIGINT / SIGTERM
- Worker shutdown
- gRPC GracefulStop
- Database connection close
+----------------+
| API Gateway |
+----------------+
|
v
+----------------+
| gRPC Service |
+----------------+
| |
v v
+--------+ +-------------+
| Worker | | PostgreSQL |
+--------+ +-------------+
|
v
+--------------+
| WebSocket Hub|
+--------------+
+------------------+
| OrderService |
|------------------|
| +CreateOrder() |
| +GetOrder() |
| +UpdateStatus() |
+------------------+
|
v
+----------------------+
| OrderRepository |
|----------------------|
| +Create() |
| +GetByID() |
| +UpdateStatus() |
+----------------------+
|
v
+----------------------------+
| PostgresOrderRepository |
+----------------------------+
Client → API Gateway → gRPC Service → Database
↓
Worker Pool
↓
WebSocket Hub
↓
Client
+------------------+
| Job Channel |
+------------------+
| | | | |
v v v v v
W1 W2 W3 W4 W5
Current system:
- Single instance
- In-memory job queue
- In-memory WebSocket subscriptions
Scaling strategy:
- Redis / Kafka job queue
- Redis Pub/Sub for WebSocket notifications
- Horizontal scaling behind load balancer
- Prometheus metrics
- OpenTelemetry tracing
- JWT authentication
- Kubernetes deployment
- Distributed worker queue
- Redis Pub/Sub for notifications
Built as a backend systems learning project demonstrating production-ready architecture using Go.
X: https://x.com/i_krsna4
LinkedIn: https://www.linkedin.com/in/krishnathakur1/