Requirements


Functional Requirements:


  • Create a short URL for a given long URL.
  • Return the long URL associated with a given short URL.



Non-Functional Requirements:


    List the key non-functional requirements (eg low latency, scalability, reliability, etc.)...


API Design

For creating short URL:

POST /shorten

Body: { longUrl: "https://example.com/very/long/url" }

Response: { shortUrl: "https://short.ly/abc123" }

For redirect:

GET /{shortCode}

Response: HTTP 301/302 redirect to original long URL



High-Level Design

Client sends request to API server.

API server handles two paths.

For creation: API receives long URL, generates a short code, stores mapping (shortCode → longUrl) in database, returns short URL.

For redirect: client hits short URL, API extracts short code, checks cache first, if found returns redirect immediately, if not queries database, gets long URL, returns redirect and optionally stores it in cache.




Detailed Component Design

When a new URL is created, the system must generate a unique short code. One approach is to use an auto-increment ID from the database and encode it into a shorter string using base62 (letters + numbers). This guarantees uniqueness and keeps the code short. Another approach is to generate a random string and check for collisions before saving, but this requires extra checks and can become inefficient at scale.

Redirect requests are much more frequent than creation. To reduce database load, a cache stores recently accessed mappings (shortCode → longUrl). On redirect, the system checks cache first, and only queries the database if the value is missing.