REST API design:
GET endpoints:
GET /api/url
POST endpoints:
POST /api/url
POST /api/url/redirect
PUT endpoints
PUT /api/url
For shortening, the client sends a long URL to the API, the service validates it, generates or reserves a unique ID, converts that ID into a compact code such as Base62, stores the mapping, and returns the final short URL. Some designs also support deduplication, where the service checks whether the same long URL already exists and reuses the existing short code.
short.ly/abc123, the service looks up abc123 in cache first, falls back to the database on a miss, and returns an HTTP redirect to the long URL. This cache-first approach is standard because it reduces database pressure and improves latency for hot links.Secure connectionsAt the edge, the load balancer should hold the server certificate, terminate TLS, and negotiate approved protocols and ciphers with clients, which is a common pattern in modern load-balancing guidance. For stricter internal security, service-to-service traffic can also use mutual TLS, especially if the platform grows into multiple services or runs in a service mesh.
For redirect safety, I would not trust arbitrary destination URLs at redirect time. Instead, the system should store a validated mapping when the short link is created, use that server-side token-to-URL mapping for redirects, and apply allow-listing or policy checks for suspicious domains to reduce open-redirect abuse.
Routing should be split by traffic type because the read path and write path behave differently. The load balancer or gateway can send /api/shorten traffic to the creation service and /{shortCode} traffic to the redirect service, while also performing health checks and removing unhealthy instances automatically.
For redirect performance, the routing path should prefer cache-first resolution, because most traffic is typically reads and many hot short codes repeat frequently. If the cache misses, the redirect service queries the backing store and can then repopulate the cache, keeping the hot path fast and reducing database load.
The storage layer is the source of truth for URL mappings, so its primary job is to persist the relationship between short_code and long_url. It also stores metadata such as creation time, expiry, owner, status, and sometimes aggregate counters or attributes needed for governance and analytics.
In practice, the storage layer is also responsible for consistency and lookup efficiency. That means supporting writes for new links, point reads by short code, uniqueness constraints for generated aliases, replication for availability, and sharding when volume becomes too large for a single node.
POST /shorten to the write path, GET /{shortCode} to the redirect path, and admin/analytics to separate handlers.short_code -> long_url, plus metadata like created_at, expires_at, user_id, and status.short_code as the primary lookup key for fast redirects.long_url if you want duplicate detection or idempotent shortening for the same user.short_code, cache value = long_url.expires_at so expired links auto-evict and are not served stale.GET /{shortCode}, check Redis first.POST /shorten than on redirects.