A user should be able send a request with a long URL and the system will return a short url
If the url is the same as the one already created, return the old short url
A user can provide the short url and get back a long url
Out of scope:
Url management page where a user can log in and change the urls they created previously
Availability - the system should be highly available
Scalability - as the number of users grows, the system should be able to handle them
Performance - the system should return results very quickly
Given there are 0.1 billion users in total
1 billion url shortening operations per month, which means
10^9 / 10^6 = approximately 1000 operations per second
1 * 10 = 10 billion urls need to stored per year, and each url takes 100 bytes for old and new, so 10 * 100 = 1 trillion bytes = 10^12 or 1 terabyte
Create a new short url:
POST v1/url/new_url_name
Response: short url
Use a tiny url:
GET v1/url/tiny_url
returns 301 code and the full url to redirect to for the browser to follow
I will pick a key-value datastore such as Dynamo DB for the database because I only need simple string to string lookups, which work perfectly for this type of datastore.
You should identify enough components that are needed to solve the actual problem from end to end. Also remember to draw a block diagram using the diagramming tool to augment your design. If you are unfamiliar with the tool, you can simply describe your design to the chat bot and ask it to generate a starter diagram for you to modify...
a post request should go user -> load balancer -> server -> key value datastore. If the url already exists, it should return an existing tiny url, otherwise it should create a new one.
a get request should follow the same path but it will return the code 301 when it finds a long url by short url, so that the browser can cache it and redirect the url automatically to the new url
The server can be a Go application because it offers a low-latency solution for handling requests and is easy to maintain. If we deploy the whole infra in AWS, then it will allow configuring auto-scaling for all components involved.
I've picked a key-value datastore rather than a typical sql database because I don't need to model complex relationships between models and create complex queries. Also, key-value datastores offer very fast performance for key lookups which will help for the given number of users. Also, no-sql solution will have very good and easy horizontal scalability.
The servers and the datastore can scale independently and automatically by design which will ensure the system can respond to a growing number of users. A firewall will help protect against incoming overwhelming requests in case of DDOS attack.
I could allow users to store urls separately from each other and not return an already existing url but always create a new url.