Estimate the scale of the system you are going to design...
Define what APIs are expected from the system...
api Endpoint :
DB schema
Data
{
shortenURL: String PK
rawURL : String
Created by : Date
}
First, client will have interaction between server (application server)
Application server will generates the hashed (shorten URL) with hashing function
check if the hashed URL existed in database -> regenerate the hashedURL, if not we can store the value (shortenURL, longURL, created by)
First client request with rawURL with post restfulAPI call /api/generateURL -> generateURL will go to application server. Application server will generate the hashed URL and store into DB
Second client request with shortenURL with GET restfulAPI call /api/getRawURL/{shorten_url} which go to application server and look for the shortenURL database and get the value to client as response
if the value not exist -> response should give failed to get RawURL
Hashing Function should work with MD5 from client IP address and time stamp and base 62 to hash the value and take first several characters (it depends on the storage requirements)
Also we can scale up the DB (RDBMS) storing the metadata to make read replica which is Read-Only DB. Also, make horizontal scaling for application server and use Load Balanacer to balancing the load.
I choose DB as RDBMS for storing MetaData -> it gives relation Database which ensure consistency compare to NoSQL which supports eventual consistency. it is hard to scale up compare to NoSQL but I use Replication for strong availability.
For cache, I will use LFU Cache, since it is useful when the situation shows there is any specific URL requested lots of time compared to others.
If we hold Load Balancer on loading request, it can be single point of failure. Also, there should be syncrhonization issue between Replica (leader and follower)
Add Analytics for logging. We can use sharding for database (by hashedURL id) it might be easier to find the URL.