A production-style URL shortener with JWT auth, Redis caching, Postgres persistence, rate limiting, and a React dashboard for link analytics.
Highlights
- JWT-based auth for creating short links
- Redis cache with TTL for hot redirects
- Postgres-backed analytics and optional link expiration
- Per-IP rate limiting on
POST /shorten - Nginx reverse proxy + Docker Compose stack
Tech Stack
- Backend: C++ (Drogon)
- Frontend: React + Vite
- Data: Postgres, Redis
- Infra: Docker, Nginx
- Load testing: k6
Quickstart (Docker Compose) This brings up the backend, database, cache, Nginx, and monitoring stack.
cd shortener
docker compose up --buildDefault endpoints:
- App (via Nginx):
http://localhost - Redis:
localhost:6379
Frontend (Vite Dev Server) Run the UI separately during development.
cd frontend
npm install
npm run devAPI Reference (Core)
POST /registerBody:{ "email": "user@example.com", "password": "Passw0rd!" }POST /loginBody:{ "email": "user@example.com", "password": "Passw0rd!" }POST /shortenHeader:Authorization: Bearer <token>Body:{ "long_url": "https://example.com", "ttl_seconds": 3600 }GET /{short_code}Redirects to the original URL (302), returns 410 if expiredGET /analytics/{short_code}Returns click count and timestamps
Environment Variables (Backend)
PORT(default5555)DB_HOST,DB_PORT,DB_NAME,DB_USER,DB_PASS,DB_SSLMODEREDIS_URLorREDIS_PUBLIC_URL(preferred)REDIS_HOST,REDIS_PORT,REDIS_USER,REDIS_PASSWORDJWT_SECRET(use 16+ chars in production)FRONTEND_ORIGIN(extra CORS allowlist entry)
Load Testing (k6) The script registers a user, logs in, creates one link, and then hammers reads.
k6 run load_test.jsRepo Structure
shortener/Backend service, Docker Compose stack, monitoring, and DB init scriptsfrontend/React UIload_test.jsk6 performance testDockerfileRoot container build for the backend
Notes
- The short link generator is deterministic; collisions are retried with a modified seed.
POST /shortenis rate-limited to 60 requests per minute per IP.