Rest API:
GET short_url/v1/{short_url}
response: 301 header: Location: long_url
POST short_url/v1/create
body: {long_url}
response: {"generated": short_url} 204 created
Use NoSQL. E.g. DynamoDB
key: short_url : string
value: long_url : string
Client -> Load Balancer -> Server -> Cache -> Database
generate url: User paste original long url and click generate short url. a POST request is made and sent to load balancer, load balancer redirects request to a server, server checks if long url exists in cache, if not, check if exists in db, if not, generate short url using base 62, store short url in database and send response 204 with short url;
use short url: user enters short url in browser, GET request sent to load balancer, load balancer redirect the request to server, server checks if short url exits in cache, then check if in db, if not return 404 not found, if yes returns 301 redirection with original long url, browser visits original long url after receiving 301 response.
To improve performance and reduce db load, we can add a cache between server and db because when a short url is created it is likely to be used often, we can use LRU cache. When a short url is created we perform write through as we need to ensure db operation is successful so that we don't lose short urls. When a short url is being used we perform read through.
we can add redundancy to load balancers to avoid single point of failure. Multiple servers are added to handle traffic load and we can add redundancy to servers for failover. we can add multiple DBs for fail over and recovery.
For the server logic, we can use hash function CRC32 to generate hash value and use predefined string to avoid collision, this will generate same length short url but complexes the system. Or we can use random number generator to generate unique id and generate string with base 62 conversion, this is simple and won't have collision but will generate different length of string. Or we can just use a random string generator to generate a string and assign it to long url this is optimal.
If we can't find short url return 404. If url is invalid, return 400 error.
If load balancer fails, use another one, if server or db fails, recover with redundancy.
If all the short url is used out, increase one character.
Create user login function so that we can help the user to manage generated url, e.g. update and delete. We can also use authentication to make it more secure.
Add rate limiter to prevent bad actors. (by IP, by machine id)
use 302 redirection so the server can collect usage of short url for analytics.