Estimate the scale of the system you are going to design...
POST "/shorturl/create"
{
original_url: ...
}
GET "/:token"
PUT "/shorturl/:shorturl_id"
{
original_url: ...
}
DELETE "/:token"
PUT "/shorturl/:shorturl_id"
{
original_url: ...
}
SHORTURL
User
Load balancer in front of services. Api gateway in front of services. Url service. Memcached. Kafka Stream. Database.
User creates a shortened url... client hits api gateway, gateway sends data to url service, url service sends data to database to create record.
User clicks a shortened url link. client hits api gateway, api gateway directs to url service, url service checks memcache for url via the url token and the url gets sent to the client and client redirects using the shortened url. At the same time the url service makes a request to memcache, it also adds the click to our stream. Every minute our worker hits the stream and does a batch update to dynamo db adding the new clicks from the kafka stream.
For deleting a url, a user must be authenticated of course. Once authenticated user will click the delete button next to the url they want to delete, we make a request to the backend, backend checks session to see if the signed in user is the created of the tiny url in question and if so deletes the tiny url.
We will have multiple URL services and when we have too much load we will spin up additional url services. When shortened url has been updated we invalidate the cache for that shortened url. When we have a cache miss we get the record from the database and update our memcache. Our worker will consume all records in our kafka stream every minute and do a batch update to our database.
Could have used a queue instead of a stream but we would have been processing one job in the queue at a time and it would be better to do a batch update instead of a bunch of singleton updates.
Our database will be backed up and we can spin up a replica if it fails. Our stream will be logged so we can recreate the stream if our stream fails so we don't miss any clicks.
What are some future improvements you would make? How would you mitigate the failure scenario(s) you described above?