An example implementation of the saga pattern in Go using microservices architecture.
This project consists of three microservices that implement a distributed saga pattern for a mortgage loan system:
- Service 1 (port 8081): Customer Service - manages customer information
- Service 2 (port 8082): Mortgage Application Service - handles mortgage applications
- Service 3 (port 8083): Loan Servicing Service - manages active loans and payments
All services share a single PostgreSQL database server but use separate databases (schemas):
service1_db- Customer databaseservice2_db- Mortgage application databaseservice3_db- Loan servicing database
- Docker and Docker Compose installed
- Ports 5432, 8081, 8082, 8083 available
From the project root directory:
# Build and start all services
docker-compose up --build
# Or run in detached mode
docker-compose up -d --buildThis will:
- Start a PostgreSQL server on port 5432
- Create three separate databases (service1_db, service2_db, service3_db)
- Build and start all three Go services
- Set up networking between services
# Stop all services
docker-compose down
# Stop and remove volumes (clears database data)
docker-compose down -v# View all logs
docker-compose logs
# View logs for a specific service
docker-compose logs service1
docker-compose logs service2
docker-compose logs service3
docker-compose logs postgres
# Follow logs in real-time
docker-compose logs -fPOST /customers- Create customerGET /customers/:id- Get customer by IDPUT /customers/:id- Update customerDELETE /customers/:id- Delete customer
POST /applications- Create mortgage applicationGET /applications/:id- Get application by IDPUT /applications/:id- Update application (approve/reject)DELETE /applications/:id- Delete applicationGET /customers/:customerId/applications- Get all applications for a customer
POST /loans- Create loanGET /loans/:id- Get loan by IDPUT /loans/:id- Update loanDELETE /loans/:id- Delete loanGET /customers/:customerId/loans- Get all loans for a customerGET /mortgages/:mortgageId/loan- Get loan by mortgage IDPOST /payments- Create paymentGET /payments/:id- Get payment by IDGET /loans/:loanId/payments- Get all payments for a loanGET /customers/:customerId/payments- Get all payments for a customer
Use the test-client.http files in each service directory to test the APIs with your HTTP client.
Connect to the PostgreSQL database:
# Using docker exec
docker exec -it saga_postgres psql -U postgres -d service1_db
docker exec -it saga_postgres psql -U postgres -d service2_db
docker exec -it saga_postgres psql -U postgres -d service3_db
# From host (if psql is installed)
psql -h localhost -U postgres -d service1_dbDefault credentials:
- Username:
postgres - Password:
postgres
Each service can be run independently for development:
# Start only the database
docker-compose up postgres
# Run service locally (example for service1)
cd service1/api
go run main.goMake sure to update the DATABASE_URL in each service's .env file if running locally.
saga-pattern/
├── docker-compose.yml # Main orchestration file
├── init-db.sql # Database initialization script
├── service1/ # Customer service
│ ├── Dockerfile
│ ├── docker-compose.yml # Individual service compose file
│ ├── api/
│ └── ...
├── service2/ # Mortgage application service
│ ├── Dockerfile
│ ├── docker-compose.yml
│ ├── api/
│ └── ...
└── service3/ # Loan servicing service
├── Dockerfile
├── docker-compose.yml
├── api/
└── ...