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:
- High Availability. Should be operational.
- Low latency, uses expect quick redirection
- Should be horizontal scalable
API Design
Get api/getUrl/:shortcode
Get :shortCode // Redirects to the original URL
Post api/shortenUrl/
High-Level Design
Client → Gateway -> API Server(Read Service/Write Service) → Cache (Redis) → URL Database
Create URL
Flow:
- Client calls POST api/shortenUrl
- Service Validates the long url
- Service generates a unique shortCode
- Service Stores the mapping in the database
- Service writes the mapping to Redis for faster future reads
- Service returns the shortened URL
```
{
"shortUrl: "",
"shortCode": ""
}
```
Read URL
Flow:
- Client request Get /:shortCode
- Service checks Redis first
- If found, return redirect
- if not found, populate redis and redirect
- if not found 404
Client connects to Gateway which will handle security and load balance
API server with rest endpoint for Get, Post and redirect
Redis for caching, we get url from redis, if we don't have it in redis, read from database and add to redis
Database, postgres for example, but I would switch to nosql db like mongodb, it has build in horizontal scalling, simple json, id and url
urls (
short_code VARCHAR PRIMARY KEY,
long_url TEXT NOT NULL,
created_at TIMESTAMP NOT NULL,
expires_at TIMESTAMP NULL,
status VARCHAR NOT NULL
)
Identifiers created using SHA-256 hash which can be truncated to a short length
Detailed Component Design
- API Layer, CQRS , API service writes data, API service reads data
- API service writes data - gets url, validates url, generates short url.
- API service reads data - get short url, checks redis, if not db writes to redis, than redirect
- Redis - cache for reading urls, to unload database
- MangoDB - horizontal scalling out of the box