{"id":29787937,"url":"https://github.com/alejandroblanco2001/go-saga","last_synced_at":"2026-04-12T18:21:48.120Z","repository":{"id":301977807,"uuid":"1010460870","full_name":"AlejandroBlanco2001/Go-SAGA","owner":"AlejandroBlanco2001","description":"A hands-on project implementing the SAGA pattern with Go, Kafka, and Kubernetes, using Helm and Skaffold to simulate a production-ready distributed transaction system","archived":false,"fork":false,"pushed_at":"2025-07-26T05:43:43.000Z","size":49,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-07-26T06:26:43.422Z","etag":null,"topics":["docker","docker-compose","golang","helm","kafka","kubernetes","skaffold"],"latest_commit_sha":null,"homepage":"","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/AlejandroBlanco2001.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-06-29T05:47:48.000Z","updated_at":"2025-07-08T01:48:02.000Z","dependencies_parsed_at":"2025-06-29T23:27:52.710Z","dependency_job_id":"3058f952-e7b3-419a-8e69-6d72e6e02f9c","html_url":"https://github.com/AlejandroBlanco2001/Go-SAGA","commit_stats":null,"previous_names":["alejandroblanco2001/go-saga"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/AlejandroBlanco2001/Go-SAGA","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AlejandroBlanco2001%2FGo-SAGA","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AlejandroBlanco2001%2FGo-SAGA/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AlejandroBlanco2001%2FGo-SAGA/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AlejandroBlanco2001%2FGo-SAGA/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/AlejandroBlanco2001","download_url":"https://codeload.github.com/AlejandroBlanco2001/Go-SAGA/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AlejandroBlanco2001%2FGo-SAGA/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":267417664,"owners_count":24083839,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-07-27T02:00:11.917Z","response_time":82,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["docker","docker-compose","golang","helm","kafka","kubernetes","skaffold"],"created_at":"2025-07-27T20:11:12.606Z","updated_at":"2026-04-12T18:21:48.095Z","avatar_url":"https://github.com/AlejandroBlanco2001.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"# SAGA Pattern implemented in Go\n\nThis is an example of how a [SAGA Pattern](https://medium.com/cloud-native-daily/microservices-patterns-part-04-saga-pattern-a7f85d8d4aa3) can be implemented using an Choreography structure in Go. This is purely educational.\n\nThis project will also showcase (using different branches) how we can simplify the life of the developer experience with the introduction of tools such as Skaffold, Helm and Make.\n\n## 🔄 **SAGA Pattern Flow**\n\nThe SAGA pattern ensures distributed transactions across microservices using event-driven choreography. When an order is created, the inventory is checked through messages, and if not available, the order is cancelled:\n\n```mermaid\nsequenceDiagram\n    participant C as Client\n    participant O as Orders Service\n    participant K as Kafka\n    participant I as Inventory Service\n    \n    Note over C,I: Order Creation SAGA\n    C-\u003e\u003eO: Create Order\n    O-\u003e\u003eO: Validate Order\n    O-\u003e\u003eK: Publish OrderCreated Event\n    K-\u003e\u003eI: Consume OrderCreated Event\n    I-\u003e\u003eI: Check Inventory\n    alt Sufficient Inventory\n        I-\u003e\u003eI: Reserve Items\n        I-\u003e\u003eK: Publish InventoryReserved Event\n        K-\u003e\u003eO: Consume InventoryReserved Event\n        O-\u003e\u003eO: Confirm Order\n        O-\u003e\u003eC: Order Confirmed\n    else Insufficient Inventory\n        I-\u003e\u003eK: Publish RevertOrder Event\n        K-\u003e\u003eO: Consume RevertOrder Event\n        O-\u003e\u003eO: Cancel Order\n        O-\u003e\u003eC: Order Cancelled\n    end\n```\n\n\n## 🏗️ **Project Structure**\n\nFor this project, we are going to show a minimal setup of 2 microservices:\n- **Order Service**: Service in charge of handling all the orders that are made to our restaurant\n- **Inventory Service**: Service in charge of handling all the deliveries to the user\n\n## 🚀 **How to run it?**\n\n\u003e [!IMPORTANT]\n\u003e On every branch you can find the SAGA pattern implemented the same way, the only thing that will change is our toolset\n\nThis is a complex question as you may think, but these are the steps depending on the branch that you are placed:\n\n---\n\n## 🔧 **Basic tooling (branch `barebones-approach`)**\n\n### 🎯 **What's in This Branch:**\n- **Docker Compose**: Simple container orchestration for development\n- **Basic Setup**: Minimal configuration for local development\n- **Volume Management**: Database persistence with Docker volumes\n\n### 📦 **Prerequisites**\n\n```bash\n# Install Docker and Docker Compose\n# (Installation instructions vary by OS)\n```\n\n### 🎯 **Quick Start**\n\n```bash\n# Run our application without cleaning the databases\nbash tooling/run-app.sh\n\n# Run our application cleaning the database (cleaning volumes)\nbash tooling/run-app.sh -c / --clean\n```\n\n### 🔧 **Available Scripts**\n\n| Script | Purpose | Usage |\n|--------|---------|-------|\n| `tooling/run-app.sh` | Start the application | `bash tooling/run-app.sh` |\n| `tooling/run-app.sh -c` | Start with clean databases | `bash tooling/run-app.sh -c / --clean` |\n\n\n### 🌐 **Service Architecture**\n\n```mermaid\nflowchart TB\n subgraph Microservices[\"Microservices\"]\n        OS[\"Orders Service\u003cbr\u003ePort: 8080\"]\n        IS[\"Inventory Service\u003cbr\u003ePort: 8081\"]\n  end\n subgraph subGraph1[\"Message Broker\"]\n        K[\"Kafka\u003cbr\u003eTopics: orders, inventory\"]\n  end\n subgraph Database[\"Database\"]\n        DBO[(\"PostgreSQL\u003cbr\u003eInventory Database\")]\n        DBI[(\"PostgreSQL\u003cbr\u003eOrders Database\")]\n  end\n    OS -- Publishes Events --\u003e K\n    IS -- Publishes Events --\u003e K\n    K -- Consumes Events --\u003e OS \u0026 IS\n    OS -- Reads/Writes --\u003e DBO\n    IS -- Reads/Writes --\u003e DBI\n\n    style OS fill:#e1f5fe\n    style IS fill:#e1f5fe\n    style K fill:#fff3e0\n```\n\n### 📋 **Service Endpoints**\n\n| Service | URL | Description |\n|---------|-----|-------------|\n| Orders API | `http://localhost:8080` | Order management endpoints |\n| Inventory API | `http://localhost:8081` | Inventory management endpoints |\n\n### ⚙️ **Configuration**\n\nThe application uses Docker Compose with the following services:\n- PostgreSQL database for each service\n- Orders microservice\n- Inventory microservice\n- Kafka message broker\n\n### 🧹 **Cleanup**\n\n```bash\n# Stop all containers\ndocker-compose down\n\n# Stop and remove volumes\ndocker-compose down -v\n\n# Remove all containers and images\ndocker-compose down --rmi all --volumes --remove-orphans\n```\n\n### 🎉 **Benefits of This Approach**\n\n- ✅ **Simple Setup**: Easy to understand and get started\n- ✅ **Docker Compose**: Familiar container orchestration\n- ✅ **Quick Development**: Fast iteration cycles\n- ✅ **Volume Persistence**: Data survives container restarts\n\n---\n\n## 🛠️ **Easier Developer Experience (branch `easier-dev-xp`)**\n\n### 🎯 **What's in This Branch:**\n\n- **Skaffold**: Automated development workflow\n- **Make**: Build automation and task management\n- **Kubernetes (Minikube)**: Container orchestration platform\n- **Automated Dependencies**: Automatic dependency checking and installation\n\n### 📦 **Prerequisites**\n\n```bash\n# Install dependencies (automated)\nmake install-dependencies\n\n# This will check and install:\n# - Docker\n# - Minikube\n# - kubectl\n# - Skaffold\n# - Make\n```\n\n### 🎯 **Quick Start**\n\n\u003e [!IMPORTANT]\n\u003e You must run the following command before making any docker related stuff \n\n```bash\nskaffold config set --global local-cluster true\neval $(minikube -p custom docker-env)\n```\n\nTo build and deploy just run:\n```bash\nmake dev\n```\n\n### 🔧 **Available Commands**\n\n| Command | Purpose | Usage |\n|---------|---------|-------|\n| `make install-dependencies` | Install required tools | `make install-dependencies` |\n| `make dev` | Start development environment | `make dev` |\n| `make clean` | Clean up resources | `make clean` |\n| `make logs` | View application logs | `make logs` |\n\n### 🌐 **Service Architecture**\n\n```mermaid\ngraph TB\n    subgraph \"Kubernetes Cluster (Minikube)\"\n        subgraph \"Microservices\"\n            OS[Orders Service\u003cbr/\u003ePort: 8080]\n            IS[Inventory Service\u003cbr/\u003ePort: 8081]\n        end\n        \n        subgraph \"Message Broker\"\n            K[Kafka StatefulSet\u003cbr/\u003eTopics: orders, inventory]\n        end\n        \n        subgraph \"Database\"\n            DBO[(PostgreSQL\u003cbr/\u003eOrders Database)]\n            DBI[(PostgreSQL\u003cbr/\u003eInvetory Database)]\n        end\n        \n        subgraph \"Development Tools\"\n            S[Skaffold\u003cbr/\u003eAuto-reload]\n            M[Make\u003cbr/\u003eTask Automation]\n        end\n    end\n    \n    OS --\u003e|Publishes Events| K\n    IS --\u003e|Publishes Events| K\n    K --\u003e|Consumes Events| OS\n    K --\u003e|Consumes Events| IS\n    \n    OS --\u003e|Reads/Writes| DBO\n    IS --\u003e|Reads/Writes| DBI\n    \n    S --\u003e|Manages| OS\n    S --\u003e|Manages| IS\n    S --\u003e|Manages| K\n    S --\u003e|Manages| DBO\n    S --\u003e|Manages| DBI\n    M --\u003e|Run| S\n    \n    style OS fill:#e1f5fe\n    style IS fill:#e1f5fe\n    style K fill:#fff3e0\n    style DBO fill:#e8f5e8\n    style DBI fill:#e8f5e8\n    style S fill:#f3e5f5\n    style M fill:#f3e5f5\n```\n\n### 📋 **Service Endpoints**\n\n| Service | URL | Description |\n|---------|-----|-------------|\n| Orders API | `http://{{minikueIP}}:30080` | Order management endpoints |\n| Inventory API | `http://{{minikueIP}}:30081` | Inventory management endpoints |\n\n### ⚙️ **Configuration**\n\nSkaffold configuration in `skaffold.yaml`:\n```yaml\napiVersion: skaffold/v2beta29\nkind: Config\nbuild:\n  artifacts:\n    - image: orders-image\n      docker:\n        dockerfile: docker/orders-command/orders.dockerfile\n    - image: inventory-image\n      docker:\n        dockerfile: docker/inventory-command/inventory.dockerfile\ndeploy:\n  kubectl:\n    manifests:\n      - k8s/orders-deployment.yaml\n      - k8s/inventory-deployment.yaml\n      - k8s/postgres-deployment.yaml\n      - k8s/kafka-deployment.yaml\n```\n\n### 🔄 **Development Workflow**\n\n```bash\n# Start development (auto-reload on changes)\nmake dev\n```\n\n### 🧹 **Cleanup**\n\n```bash\n# Stop Skaffold\nCtrl+C (in the make dev terminal)\n\n# Stop Minikube\nminikube stop\n```\n\n### 🎉 **Benefits of This Approach**\n\n- ✅ **Automated Workflow**: Skaffold handles build and deploy\n- ✅ **Hot Reload**: Automatic rebuilds on code changes\n- ✅ **Kubernetes Native**: Real container orchestration\n- ✅ **Task Automation**: Make simplifies common tasks\n- ✅ **Dependency Management**: Automatic tool installation\n\n---\n\n## 🎯 **Don't want to repeat, let's template (branch `helm-is-here`)**\n\n### 🎯 **What's in This Branch:**\n\n- **Helm Charts**: Templated Kubernetes manifests with configurable values\n- **Ingress Controller**: Path-based routing for microservices\n- **Automated Setup Scripts**: One-command deployment and configuration\n- **Separate Databases**: Each microservice has its own PostgreSQL instance\n- **Kafka Integration**: Message broker for SAGA pattern communication\n\n### 📦 **Prerequisites**\n\n```bash\n# Install Helm (if not already installed)\ncurl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash\n\n# Start Minikube and enable ingress\nminikube start\nminikube addons enable ingress\n```\n\n### 🎯 **Quick Start**\n\n#### **Option 1: Manual Step-by-Step**\n```bash\n# 1. Deploy the Helm chart\ncd k8s\nhelm install saga-go .\n\n# 2. Set up ingress hosts\nsudo ./setup-ingress.sh\n\n# 3. Access your services\n# Orders API: http://saga-go.local/orders\n# Inventory API: http://saga-go.local/inventory\n# Kafka UI: http://saga-go.local/kafka-ui\n```\n\n### 🔧 **Available Scripts**\n\n| Script | Purpose | Usage |\n|--------|---------|-------|\n| `setup-ingress.sh` | Setup ingress hosts only | `sudo ./setup-ingress.sh` |\n| `cleanup-ingress.sh` | Remove ingress hosts | `sudo ./cleanup-ingress.sh` |\n\n### 🌐 **Service Architecture**\n\n```mermaid\ngraph TB\n    subgraph \"External Access\"\n        U[User/Browser]\n    end\n    \n    subgraph \"Kubernetes Cluster (Minikube)\"\n        subgraph \"Ingress Layer\"\n            I[NGINX Ingress\u003cbr/\u003esaga-go.local]\n        end\n        \n        subgraph \"Microservices\"\n            OS[Orders Service\u003cbr/\u003ePort: 8080]\n            IS[Inventory Service\u003cbr/\u003ePort: 8081]\n            KU[Kafka UI\u003cbr/\u003ePort: 8080]\n        end\n        \n        subgraph \"Message Broker\"\n            K[Kafka StatefulSet\u003cbr/\u003eTopics: orders, inventory]\n        end\n        \n        subgraph \"Databases\"\n            DB1[(PostgreSQL Orders\u003cbr/\u003eorders_database)]\n            DB2[(PostgreSQL Inventory\u003cbr/\u003einventory_database)]\n        end\n        \n        subgraph \"Orchestration\"\n            H[Helm Charts\u003cbr/\u003eTemplated Manifests]\n        end\n    end\n    \n    U --\u003e|HTTP Requests| I\n    I --\u003e|/orders/*| OS\n    I --\u003e|/inventory/*| IS\n    I --\u003e|/kafka-ui/*| KU\n    \n    OS --\u003e|Publishes Events| K\n    IS --\u003e|Publishes Events| K\n    K --\u003e|Consumes Events| OS\n    K --\u003e|Consumes Events| IS\n    \n    OS --\u003e|Reads/Writes| DB1\n    IS --\u003e|Reads/Writes| DB2\n    \n    H --\u003e|Manages| OS\n    H --\u003e|Manages| IS\n    H --\u003e|Manages| K\n    H --\u003e|Manages| DB1\n    H --\u003e|Manages| DB2\n    H --\u003e|Manages| I\n    \n    style U fill:#f5f5f5\n    style I fill:#e3f2fd\n    style OS fill:#e1f5fe\n    style IS fill:#e1f5fe\n    style KU fill:#e1f5fe\n    style K fill:#fff3e0\n    style DB1 fill:#e8f5e8\n    style DB2 fill:#e8f5e8\n    style H fill:#f3e5f5\n```\n\n### 📋 **Service Endpoints**\n\n| Service | URL | Description |\n|---------|-----|-------------|\n| Orders API | `http://saga-go.local/orders` | Order management endpoints |\n| Inventory API | `http://saga-go.local/inventory` | Inventory management endpoints |\n| Kafka UI | `http://saga-go.local/kafka-ui` | Kafka management interface |\n\n### ⚙️ **Configuration**\n\nThe Helm chart is highly configurable through `values.yaml`:\n\n```yaml\n# Application configuration\nreplicaCount: 1\n\n# Database configuration\nconfiguration:\n  postgres:\n    port: \"5432\"\n    user: myuser\n    password: somerandompassword\n  orders:\n    host: postgres-orders\n    database_name: orders_database\n  inventory:\n    host: postgres-inventory\n    database_name: inventory_database\n\n# Ingress configuration\ningress:\n  enabled: true\n  className: \"nginx\"\n  hosts:\n    - host: saga-go.local\n      paths:\n        - path: /orders\n          service: orders-service\n        - path: /inventory\n          service: inventory-service\n        - path: /kafka-ui\n          service: kafka-ui\n```\n\n### 🔄 **Upgrading the Deployment**\n\n```bash\n# First time deployment\nmake create-helm\n\n# New deployment\nmake upgrade-helm\n```\n\n### 🧹 **Cleanup**\n\n```bash\n# Remove ingress hosts\nsudo ./cleanup-ingress.sh\n\n# Uninstall Helm chart\nmake delete-helm\n```\n\n### 🔍 **Troubleshooting**\n\n#### **Ingress not working?**\n```bash\n# Check ingress status\nkubectl get ingress\nkubectl describe ingress saga-go-ingress\n\n# Check if pods are running\nkubectl get pods\n\n# Check ingress controller\nkubectl get pods -n ingress-nginx\n```\n\n#### **Services not accessible?**\n```bash\n# Check service endpoints\nkubectl get endpoints\n\n# Check service logs\nkubectl logs -f deployment/orders-service\nkubectl logs -f deployment/inventory-service\n```\n\n#### **Database connection issues?**\n```bash\n# Check database pods\nkubectl get pods | grep postgres\n\n# Check database logs\nkubectl logs -f deployment/postgres-orders\nkubectl logs -f deployment/postgres-inventory\n```\n\n### 🎉 **Benefits of This Approach**\n\n- ✅ **Templated Configuration**: No more duplicate YAML files\n- ✅ **Version Control**: Track changes to your deployment configuration\n- ✅ **Easy Scaling**: Change replica counts with simple commands\n- ✅ **Environment Separation**: Use different values for dev/staging/prod\n- ✅ **Automated Setup**: One command to deploy everything\n- ✅ **Proper Routing**: Ingress handles external traffic routing\n- ✅ **Database Isolation**: Each service has its own database\n\n---\n\n## 📚 **References**\n\nThis were some of the posts and articles that I read to make this project:\n- [Database per Microservice pattern](https://microservices.io/patterns/data/database-per-service.html)\n- [SAGA Pattern](https://medium.com/cloud-native-daily/microservices-patterns-part-04-saga-pattern-a7f85d8d4aa3)\n- [Helm Documentation](https://helm.sh/docs/)\n- [Skaffold Documentation](https://skaffold.dev/docs/)\n- [Kubernetes Ingress](https://kubernetes.io/docs/concepts/services-networking/ingress/)","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falejandroblanco2001%2Fgo-saga","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Falejandroblanco2001%2Fgo-saga","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falejandroblanco2001%2Fgo-saga/lists"}