A high-performance, stateless, serverless-optimized URL shortener and QR generator backend built on Spring Boot, PostgreSQL (Neon), and Redis (Upstash).
QuickLink provides lightweight URL shortening with automatic sub-50ms cache resolution, AOP execution logging, JWT-gated custom aliases, and automatic API documentation.
graph TD
Client[Client / Browser] -->|GET /code| Controller[RedirectController]
Client -->|POST /api/quicklinks| QLController[QuickLinkController]
Controller -->|1. Cache Lookup| Redis[(Upstash Redis)]
Controller -->|2. DB Fallback| DB[(Neon PostgreSQL)]
QLController -->|Gate Custom Alias| Security[Spring Security / JWT]
- Core Engine: Java 17 / Spring Boot 3.x (stateless architecture)
- Security & Auth: Spring Security 6 + stateless JWT bearer authentication (
com.auth0:java-jwt) - Persistence Layer: Spring Data JPA + Hibernate 6 on Neon Serverless PostgreSQL
- Caching Layer: Spring Data Redis on Upstash Serverless Redis (sub-50ms cache hits)
- QR Engine: Google ZXing (Zebra Crossing) for real-time vector image generation
- API Documentation: OpenAPI 3 / Swagger UI via
springdoc-openapi - Performance Monitoring: AspectJ AOP (custom logger capturing execution time metrics)
- Cleanup Engine: Daily
@Scheduledcron worker managing database garbage collection
- DB-Direct Redirect Lookup (Cold):
~500ms - 600ms - Redis Cache Hit (Warm):
~30ms - 50ms(Over 10x latency reduction)
QuickLink manages secrets using a stateless .env configuration imported directly into the Spring runtime context.
Create a .env file in the root of the project:
# Neon PostgreSQL Datasource
DB_URL=jdbc:postgresql://<neon-db-url>/neondb?sslmode=require
DB_USER=neondb_owner
DB_PASSWORD=<neon-password>
# Upstash Redis Cache
REDIS_URL=<upstash-redis-endpoint>
REDIS_PORT=6379
REDIS_PASSWORD=<upstash-redis-password>To keep queries fast as link logs grow, the schema utilizes optimized B-Tree indexes:
idx_code_uniqueonquick_link(code)– guarantees instant O(1) resolution during redirection lookups.idx_user_usernameonquick_user(username)– ensures fast authentication queries.
GET /{code}- Redirects (302 Found) the browser to the destination target URL.
- Optimized Flow: Resolves from Redis first. On cache miss, queries DB, registers hit async, writes back to Redis cache (30-min TTL), and redirects.
POST /api/quicklinks- Shortens a target URL.
- Payload:
{ "url": "https://example.com", "alias": "customBrand", // Optional, requires JWT Auth "expiryDays": 5 // Optional, defaults to 1 day } - Rules: Anonymous users get a random Base-62 generated string of length 7. Custom aliases require a valid
Authorization: Bearer <token>header.
POST /api/auth/register– Creates a user, hashes password using BCrypt, and returns a JWT token.POST /api/auth/login– Validates credentials and returns a JWT token.
GET /api/quicklink/qrcode- Generates and returns a PNG QR code representation of the given text.
- Params:
url(String),width(Int, default 250),height(Int, default 250).
- Swagger Interactive UI:
http://localhost:8080/swagger-ui/index.html - Raw OpenAPI Specification:
http://localhost:8080/v3/api-docs
An asynchronous cron scheduler runs daily at midnight (@Scheduled(cron = "@midnight")) inside QuickLinkUrlCleanUpService to delete expired links and release database storage.