# URL Shortener - Distributed Systems Learning Project A URL shortening service designed to teach distributed systems concepts. ## Architecture ``` [Client] --> [Nginx LB] --> [API Server 1] --> [Redis Cache] --> [PostgreSQL] --> [API Server 2] --> --> [API Server 3] --> ``` ## Concepts Covered | Concept | Implementation | |---------|----------------| | Load Balancing | Nginx with least_conn algorithm | | Caching | Redis with read-through pattern | | Unique ID Generation | Snowflake IDs (Twitter-style) | | Encoding | Base62 for short URLs | | Rate Limiting | Nginx rate limiting (10 req/sec/IP) | | Async Processing | Fire-and-forget click tracking | ## Quick Start ```bash # Start all services docker compose up -d # Scale API servers to 3 instances docker compose up -d --scale api=3 # Test the service curl -X POST http://localhost/shorten \ -H "Content-Type: application/json" \ -d '{"url": "https://example.com/very/long/path"}' # Follow the redirect curl -L http://localhost/{short_code} # Get stats curl http://localhost/stats/{short_code} ``` ## Local Development (without Docker) ```bash # Install dependencies uv venv source .venv/bin/activate uv pip install -e ".[dev]" # Start PostgreSQL and Redis (via Docker) docker compose up -d postgres redis # Run the API server uvicorn app.main:app --reload ``` ## API Endpoints | Method | Endpoint | Description | |--------|----------|-------------| | POST | /shorten | Create a short URL | | GET | /{code} | Redirect to original URL | | GET | /stats/{code} | Get click statistics | | GET | /health | Health check | ## File Structure ``` . |-- app/ | |-- main.py # FastAPI application | |-- encoding.py # Base62 encoding | |-- snowflake.py # Distributed ID generation |-- db/ | |-- init.sql # Database schema |-- nginx/ | |-- nginx.conf # Load balancer config |-- docker-compose.yml |-- Dockerfile |-- pyproject.toml ```