A production-ready URL shortening service built with FastAPI, PostgreSQL, and Redis.
Designed with best practices for scalability, performance, and security in mind.
- Shorten URLs with unique 5-character Base62 codes
- Fast redirects with Redis positive and negative caching
- Rate limiting on URL creation to prevent abuse
- Database migrations with Alembic (automatically run on container startup)
- Full Docker Compose setup (API, PostgreSQL, Redis)
- End-to-End tests with Pytest and Httpx
- Clean and modular project structure
Before running the containers, create a .env file by copying the example:
cp .env.example .envThis file contains configuration values for the database, Redis, cache, and rate limiting.
docker-compose up --buildThe API will be available at: http://localhost:5050/docs
Database migrations will be executed automatically when the API container starts.
docker-compose run api pytest -vOnce the containers are up, the API will be available at http://localhost:5050.
Send a POST request to create a shortened link:
curl -X POST "http://localhost:5050/shorten" \
-H "Content-Type: application/json" \
-d '{"target_url": "https://example.com"}'Response:
{
"code": "abc12",
"target_url": "https://example.com"
}Open the shortened link in your browser or via curl:
curl -i http://localhost:5050/abc12You will be redirected (HTTP 307) to the original target_url.
After starting the application, you can access the interactive API documentation:
- Swagger UI: http://localhost:5050/docs
- ReDoc: http://localhost:5050/redoc
app/
├── main.py # FastAPI application entrypoint
├── models.py # SQLAlchemy models
├── schemas.py # Pydantic schemas
├── crud.py # Database operations
├── cache.py # Redis connection
├── rate_limiter.py # Request throttling logic
└── database.py # DB engine & session
migrations/ # Alembic migrations
tests/ # Pytest test suite
docker-compose.yml
Developed by Ali Mohammadi