This is a minimal but realistic cloud-native reference implementation showing a small service topology wired together with NATS JetStream events.
gateway-api— thin HTTP gateway proxying to backend servicesuser-service— creates users and emitsuser.created.v1asset-service— creates assets and emitsasset.created.v1aggregator-service— listens toasset.created.v1and maintains an in-memory view
NATS JetStream is used for events, Postgres is provided for future persistence, and Jaeger is provided for tracing (not yet wired but ready).
# 1. Start infra (NATS, Postgres, Jaeger)
make dev-infra
# 2. In separate terminals, run each service
HTTP_PORT=8080 go run ./cmd/gateway-api
HTTP_PORT=8081 go run ./cmd/user-service
HTTP_PORT=8082 go run ./cmd/asset-service
HTTP_PORT=8083 go run ./cmd/aggregator-serviceCreate a user:
curl -X POST http://localhost:8081/users \ -H "Content-Type: application/json" \ -d '{"email":"ray@example.com","name":"Ray"}'Create an asset:
curl -X POST http://localhost:8082/assets \ -H "Content-Type: application/json" \ -d '{"owner_id":"<user-id-from-response>","label":"My First Asset"}'Check the in-memory materialized view:
curl http://localhost:8083/view/assets | jqOr route traffic via the gateway (when you extend it to support more paths).
HTTP_PORT— port to bind each service (default: 8080)NATS_URL— NATS connection URL (default:nats://127.0.0.1:4222)USER_SERVICE_URL— (gateway) URL for the user service (default:http://localhost:8081)ASSET_SERVICE_URL— (gateway) URL for the asset service (default:http://localhost:8082)
- Add persistence layers (Postgres) to user/asset services
- Wire tracing via OpenTelemetry and send to Jaeger
- Expand contract types and event flows
- Replace in-memory aggregator state with a real read model
- Add CI workflows for lint, test, and build