Project breakdown · Learning Project
Shortly
A full-stack learning project for creating and managing short links, resolving redirects, and reviewing privacy-conscious analytics.
Why I built it
I wanted a focused backend problem that would let me practice HTTP behavior, API routes, redirects, and organizing Python code beyond a single file.
What works today
Anonymous shortening, account-based link management, redirects, QR codes, basic analytics, tests, Docker configuration, and local SQLite or PostgreSQL persistence are implemented in the repository.
What I wanted to learn
- Practice backend development with Python and FastAPI.
- Understand creation, authentication, and redirect request flows.
- Separate routing, persistence, caching, and analytics responsibilities.
How it works
- Define focused link-management and redirect routes.
- Record privacy-conscious click metadata at redirect time.
- Keep Redis optional by falling back to durable database lookups.
Technical structure
A React and TypeScript frontend talks to a modular FastAPI API. SQLAlchemy and Alembic handle persistence, while optional Redis caching speeds up redirects without becoming the source of truth. Backend and frontend tests cover core workflows.
Testing
- Pytest files cover authentication, links, services, and HTTP hardening using local SQLite. A frontend ShortenForm test covers the submission interface.
- CI includes lint, tests, a frontend build, and a clean database migration.
Technical decisions
- Treat Redis as an optimization and fall back to indexed database lookups when it is unavailable.
- Hash a rotating visitor identifier instead of storing raw IP addresses.
- Use typed API boundaries and separate routes, services, repositories, and models.
Challenges
Keep redirect behavior simple while separating API, data, and analytics responsibilities.
What I learned
Shortly gave me practice thinking in request and response boundaries, handling redirects, and keeping a small backend understandable as features are added.
What I'd improve next
Add refresh-token rotation, improve bot filtering, and move analytics processing to a bounded queue if the project ever needs sustained-volume handling.