User want to be able to enter a URL and received a shortened one
User wants to access a link via shorted url
High-Availability
Low-Latency
Reliability - After creating the URL must exist
Global
Unique
URL length of 6-12
10.000.000 daily; Seconds in a day = 100.000;
Writes = 10/s
Read = 1000/s
Original Url Average Size = 100
Shortened = 8
MetaData = View, User, lock access, = 1kb
Total we can consider 2Kb;
Storage
2KB * 10Mi * 365 = 730GB of storage
The system would need authentication for the creation route and maybe for reading if is an private URL
POST /url
Description: Creates a new url
Header: Authorization JWT
Body: {
URL: string,
expiration: number,
private: bool,
}
Response {
shortenedUrl: string
}
GET /url/:shortenedUrl
Description: fetch the original link
Header: (Optional) Authorization JWT
Response: {
originalUrl: string
}
-- Adicionatal Routes
GET /url/list
Description: Fetch the created links sorted by created at
Header - Authorization JWT
Params: { first, skip }
Response {
data: [
{
id: ...,
URL: string,
views: number
}
]
}
PUT /url/:shortenedUrl/permission
Header - Authorization JWT
Description: Update the permission of a given url
Body {
allowed: [
//list of allowed user
]
}
Response {
ok: ..
}
// url
{
id: number,
title: string
description: string
originalUrl: string
shortenedUrl: string,
private: false,
views: number,
allowedUsers: [id] @reference to the userId
}
The system will be composes by The client accessing the by an load balancer or an API gateway
One path way connecting into the server into the database, a nosql database. We need to scale, so It could be lambda functions because It will handle properly the large amount of the request
For the read part, is desirable to have a CDN content for caching the content of the most access URLs. Also a redis cache for updating the views an latter update the database
Creating a post
Client Trigger via Load balancer, in this stage the user is identify via an API Gateway by an authentication service like coginito, and we can record the request limit and also the auth of the user.
Next, the URL shortening service is called, the process of URL been encode is executed and the new URL data is stored in the dynamodb. Some notification can be attached to this event of creation complete so other services could handle this event.
For reading the URL the user makes a request to the CDN, if not find, then goes to the LB to be served by the URL shorten service. The service can directly fetch by the database or we could use the redis cache as a second cache layer for better latency.
There is a lot of bottle necks like:
Rate limit
Cost in scale the lambda.
The design dosent cover things like monitoring;
Privacy and expiration; We would need jobs for timely remove the URL or remove the access of some URLs;
Better attacks and security handle;
How do we check if the URL still exists and is not a dead URL?