A production-grade Go application demonstrating a real-time e-commerce order processing system with:
- Producer API → writes to sharded Postgres + S3 + publishes to Kafka
- Consumer Service → reads from Kafka only (no S3/Postgres access by design)
- Frontend Dashboard → real-time order placement and monitoring
Frontend (index.html)
│
│ POST /api/orders
▼
┌─────────────────┐
│ Producer API │ (Go HTTP Server, :8080)
│ (main.go) │
└────┬────┬───────┘
│ │ │
│ │ │ 1. INSERT
│ │ ▼
│ │ ┌─────────────────┐ ┌─────────────────┐
│ │ │ Postgres Shard1 │ │ Postgres Shard2 │
│ │ │ Users A-M :5432 │ │ Users N-Z :5433 │
│ │ └─────────────────┘ └─────────────────┘
│ │
│ │ 2. PUT (receipt .txt)
│ ▼
│ ┌──────────────────────┐
│ │ S3 (LocalStack) │
│ │ bucket:order-receipts│
│ │ port :4566 │
│ └──────────────────────┘
│
│ 3. PUBLISH (order.created event)
▼
┌─────────────────┐ CONSUME ┌─────────────────┐
│ Kafka │ ──────────────► │ Consumer │
│ topic: orders │ │ (Go Service) │
│ port: :9092 │ │ Kafka only │
└─────────────────┘ │ ❌ No S3/Postgres│
└─────────────────┘
Orders are sharded by the first letter of user_id:
- Shard 1 (port 5432): Users whose ID starts with A–M
- Shard 2 (port 5433): Users whose ID starts with N–Z
orderflow/
├── docker-compose.yml # All services orchestration
├── frontend/
│ └── index.html # Dashboard UI
├── producer/ # Producer API (Go)
│ ├── main.go # Entry point, HTTP server
│ ├── Dockerfile
│ ├── go.mod
│ ├── config/
│ │ └── config.go # ENV-based config
│ ├── models/
│ │ └── order.go # Order structs + Kafka event
│ ├── handlers/
│ │ └── order.go # HTTP handlers (create, list)
│ ├── kafka/
│ │ └── producer.go # Kafka producer client
│ └── storage/
│ ├── postgres.go # Sharded Postgres (shard1 + shard2)
│ └── s3.go # S3 receipt upload
├── consumer/ # Consumer Service (Go)
│ ├── main.go # Kafka consumer loop
│ ├── Dockerfile
│ ├── go.mod
│ ├── config/
│ │ └── config.go
│ └── handlers/
│ └── processor.go # Event processor (Kafka only, no S3/PG)
└── scripts/
├── init_shard1.sql # Postgres schema for shard 1
├── init_shard2.sql # Postgres schema for shard 2
└── init_localstack.sh # Creates S3 bucket on startup
- Docker and Docker Compose installed
- Go 1.21+ (only for local dev without Docker)
- librdkafka (only for local dev —
brew install librdkafkaon Mac)
cd orderflowchmod +x scripts/init_localstack.shdocker-compose up --buildWait ~30 seconds for all services to initialize. You'll see:
producer | ✓ Connected to sharded Postgres (shard1: A-M, shard2: N-Z)
producer | ✓ S3 client initialized (bucket: order-receipts)
producer | ✓ Kafka producer connected to kafka:9092
producer | ✓ Producer API listening on :8080
consumer | ✓ Subscribed to topic 'orders' with group 'order-consumer-group'
consumer | ✓ Waiting for messages...
Open frontend/index.html in your browser (just double-click the file), or:
open frontend/index.html # Mac
xdg-open frontend/index.html # Linuxdocker-compose up zookeeper kafka postgres_shard1 postgres_shard2 localstackcd producer
go mod tidy
export PG_SHARD1_DSN="postgres://orderuser:orderpass@localhost:5432/orders_shard1?sslmode=disable"
export PG_SHARD2_DSN="postgres://orderuser:orderpass@localhost:5433/orders_shard2?sslmode=disable"
export S3_ENDPOINT="http://localhost:4566"
export KAFKA_BROKERS="localhost:9092"
CGO_ENABLED=1 go run main.gocd consumer
go mod tidy
export KAFKA_BROKERS="localhost:9092"
CGO_ENABLED=1 go run main.gocurl http://localhost:8080/healthcurl -X POST http://localhost:8082/api/orders \
-H "Content-Type: application/json" \
-d '{
"user_id": "alice",
"product_name": "Mechanical Keyboard",
"quantity": 2,
"price": 149.99
}'Response:
{
"order": {
"id": "uuid-here",
"user_id": "alice",
"product_name": "Mechanical Keyboard",
"quantity": 2,
"price": 149.99,
"status": "created"
},
"shard": "shard1",
"shard_info": "shard1 (A-M)",
"receipt": "receipts/alice/uuid-here.txt"
}curl http://localhost:8080/api/orderscurl "http://localhost:8080/api/orders?user_id=alice"# This goes to Shard 1 (A-M)
curl -X POST http://localhost:8080/api/orders \
-H "Content-Type: application/json" \
-d '{"user_id":"alice","product_name":"Monitor","quantity":1,"price":399.99}'
# This goes to Shard 2 (N-Z)
curl -X POST http://localhost:8080/api/orders \
-H "Content-Type: application/json" \
-d '{"user_id":"zara","product_name":"Keyboard","quantity":2,"price":99.99}'
# Verify directly in Postgres
docker exec -it orderflow-postgres_shard1-1 psql -U orderuser -d orders_shard1 -c "SELECT id, user_id, product_name FROM orders;"
docker exec -it orderflow-postgres_shard2-1 psql -U orderuser -d orders_shard2 -c "SELECT id, user_id, product_name FROM orders;"aws --endpoint-url=http://localhost:4566 s3 ls s3://order-receipts/receipts/ --recursivedocker exec -it orderflow-kafka-1 kafka-console-consumer \
--bootstrap-server localhost:9092 \
--topic orders \
--from-beginning| Variable | Default | Description |
|---|---|---|
KAFKA_BROKERS |
localhost:9092 |
Kafka broker addresses |
PG_SHARD1_DSN |
local shard1 | Postgres DSN for shard 1 |
PG_SHARD2_DSN |
local shard2 | Postgres DSN for shard 2 |
S3_ENDPOINT |
http://localhost:4566 |
S3/LocalStack endpoint |
S3_BUCKET |
order-receipts |
S3 bucket name |
PORT |
8080 |
HTTP server port |
| Variable | Default | Description |
|---|---|---|
KAFKA_BROKERS |
localhost:9092 |
Kafka broker addresses |
KAFKA_GROUP_ID |
order-consumer-group |
Consumer group ID |
KAFKA_TOPIC |
orders |
Topic to consume |
docker-compose down -v