Getting Started with Saga Service Discovery
Saga is a centralized service discovery system that enables microservices to register themselves and discover other services dynamically. Built with Rust and Actix Web, Saga provides high-performance service discovery with Redis-backed storage and comprehensive HTTP API and CLI interfaces.
Service discovery is a key component of microservices architectures that allows services to find and communicate with each other without hardcoded URLs. Saga provides this capability with automatic registration, health monitoring, and dynamic routing.
Prerequisites
Before you begin, ensure you have the following installed:
- Rust
- Redis
- Docker (Optional)
# Install Rust using rustup
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
# Verify installation
rustc --version
cargo --version
# Using Docker (recommended)
docker run -d -p 6379:6379 redis:7-alpine
# Or install locally (macOS)
brew install redis
brew services start redis
# Verify Redis is running
redis-cli ping
# Expected: PONG
# Install Docker Desktop
# Visit: https://www.docker.com/products/docker-desktop
# Verify installation
docker --version
docker compose version
If you're using Docker Compose, Redis is already configured in infra/compose.yml. Simply run docker compose -f infra/compose.yml up -d redis to start Redis.
Quick Start
Follow these steps to get Saga running locally in under 5 minutes.
Step 1: Start Redis
Saga requires Redis as its backend storage. Choose your preferred method:
- Docker Compose
- Docker Standalone
- Local Installation
# From the project root
cd /Users/mitch/work/one
docker compose -f infra/compose.yml up -d redis
# Verify Redis is healthy
docker compose -f infra/compose.yml ps redis
NAME STATUS
redis Up (healthy)
docker run -d \
--name redis \
-p 6379:6379 \
redis:7-alpine
# Verify connection
docker exec redis redis-cli ping
# Start Redis server
redis-server
# In another terminal, verify
redis-cli ping
# Should return: PONG
If Redis is not accessible, Saga will start but service registration and discovery will fail. Always verify Redis connectivity before proceeding.
Step 2: Start Saga Service
Start Saga in development mode using one of these methods:
- Makefile (Recommended)
- Cargo Direct
- With Hot Reload
# From project root
REDIS_URL=redis://localhost:6379 PORT=8030 HOST=0.0.0.0 make saga-dev
The Makefile provides a consistent interface across all services and handles environment setup automatically.
cd shared/saga
REDIS_URL=redis://localhost:6379 PORT=8030 cargo run
# Using Makefile watch mode
make saga-watch
# Or with cargo watch
cd shared/saga
cargo watch -x run
Use cargo watch for automatic restarts on code changes. This significantly speeds up development iteration.
Step 3: Verify Saga is Running
Check the health endpoint to confirm Saga is operational:
curl http://localhost:8030/api/v1/health | jq .
{
"status": "healthy",
"service": "saga",
"version": "0.8.1",
"redis": "connected",
"cache": {
"size": 0,
"hits": 0,
"misses": 0,
"hit_ratio": 0.0,
"last_refresh": "2025-12-22T14:29:53.944455Z"
}
}
- status: Overall service health (
healthyorunhealthy) - redis: Connection status (
connectedordisconnected) - cache: In-memory cache statistics for performance monitoring
- version: Current Saga version
If redis shows disconnected, check your Redis connection and REDIS_URL environment variable.
Testing Locally
Now that Saga is running, let's test the core functionality with practical examples.
Register a Test Service
Register a service to test the registration functionality:
curl -X POST http://localhost:8030/api/v1/services/register \
-H "Content-Type: application/json" \
-d '{
"service_name": "test-service",
"service_url": "http://localhost:8080",
"capabilities": ["rest"]
}'
{
"service_name": "test-service",
"service_url": "http://localhost:8080",
"service_id": "a674dbe7-5147-441b-ae56-f1c05f61cdbd",
"registered_at": "2025-12-22T14:30:38.531328+00:00",
"capabilities": ["rest"],
"ttl": 60
}
Key Fields Explained:
- service_id: Unique UUID assigned to this registration
- registered_at: Timestamp when the service was registered
- ttl: Time-to-live in seconds (service expires after 60 seconds without heartbeat)
Valid capabilities include: rest, graphql, grpc, and mcp. Services can declare multiple capabilities:
{
"service_name": "api-gateway",
"service_url": "http://localhost:8000",
"capabilities": ["rest", "graphql", "grpc"]
}
List All Services
Retrieve a list of all registered services:
curl http://localhost:8030/api/v1/services | jq .
{
"services": [
{
"service_name": "test-service",
"service_url": "http://localhost:8080",
"service_id": "a674dbe7-5147-441b-ae56-f1c05f61cdbd",
"registered_at": "2025-12-22T14:30:38.531328+00:00",
"last_heartbeat": "2025-12-22T14:30:38.531330+00:00",
"capabilities": ["rest"]
}
],
"total": 1
}
Understanding the Response:
- services: Array of all registered services with full metadata
- total: Count of registered services
- last_heartbeat: Last time the service sent a heartbeat (keeps registration alive)
Discover a Specific Service
Query details for a specific service by name:
curl http://localhost:8030/api/v1/services/test-service | jq .
{
"service_name": "test-service",
"service_url": "http://localhost:8080",
"service_id": "a674dbe7-5147-441b-ae56-f1c05f61cdbd",
"registered_at": "2025-12-22T14:30:38.531328+00:00",
"last_heartbeat": "2025-12-22T14:30:38.531330+00:00",
"capabilities": ["rest"]
}
Services expire after their TTL (default 60 seconds) if no heartbeat is received. Always implement heartbeat logic in your services to keep registrations alive.
Using the CLI
Saga provides a comprehensive command-line interface for managing services without making HTTP requests.
List Services
cd shared/saga
cargo run -- service list
Output:
2025-12-22T14:30:13.951320Z INFO saga::services::registration: Listed 0 registered services
No services registered.
Register a Service
cargo run -- service register \
--name my-service \
--url http://localhost:8000 \
--capabilities rest,graphql
The CLI is convenient for manual operations and scripts, while the API is better for programmatic integration in your services.
Get Service Details
cargo run -- service get my-service
Unregister a Service
cargo run -- service unregister my-service
Get help for any command:
cargo run -- --help
cargo run -- service --help
cargo run -- service register --help
Development Workflow
Running in Development Mode
For active development with hot reload:
- Makefile
- Cargo Watch
# Start with watch mode
make saga-watch
cd shared/saga
cargo watch -x run
Features:
- Automatically rebuilds on file changes
- Restarts the server automatically
- Shows compilation errors immediately
Running Tests
- All Tests
- Ignored Tests (Requires Redis)
# Using Makefile
make saga-test
# Or using cargo
cd shared/saga
cargo test
Test Coverage:
- Unit tests for core functionality
- Integration tests for API endpoints
- End-to-end tests for complete workflows
cd shared/saga
cargo test -- --ignored
- Unit tests: Fast, no external dependencies
- Integration tests: Require Redis, test API endpoints
- Ignored tests: Require full Redis setup, skipped in CI by default
Common Workflows
Complete Service Registration Flow
Here's a complete example of registering and using a service:
# 1. Register the service
curl -X POST http://localhost:8030/api/v1/services/register \
-H "Content-Type: application/json" \
-d '{
"service_name": "authentication",
"service_url": "http://localhost:8001",
"capabilities": ["rest", "graphql"]
}'
# 2. Verify registration
curl http://localhost:8030/api/v1/services/authentication
# 3. Send heartbeat to keep it alive
curl -X POST http://localhost:8030/api/v1/services/authentication/heartbeat
# 4. Discover from another service
curl http://localhost:8030/api/v1/services/authentication
- Register on startup: Register your service when it starts
- Implement heartbeats: Send heartbeats every 30 seconds to keep registration alive
- Handle failures: Implement fallback logic if Saga is unavailable
- Monitor health: Check Saga health endpoint regularly
Next Steps
Now that you have Saga running locally, explore these resources:
- API Reference - Complete endpoint documentation with examples
- Configuration - Environment variables and configuration options
- Integration Examples - Code examples for Rust and Python services
- Deployment Guide - Production deployment strategies
- Architecture - System design and component details
- Troubleshooting - Common issues and solutions
Saga is now running and ready for integration. Start registering your services and discover the power of dynamic service discovery!