We would want to have 2 types of APIs - one APi would be serving the get request and the URL would look something like this:
co.me/url-link-short.
This API would redirect the sender to the actual resource and on success return 302 (redirected) and on fail we can return something like 404
The other API would to let the user encode their URL through the UI portal. We may allow them specify the URL themselves (which internally would be translated into a hash that can be easily used to locate the node with the the link on it.
We may also want to ensure that the links ecnoded aren't malicious or point to dark web/denied reosuces. If a user tries to encode something like that, we may deny the request on create API flow.
We are going to have to have a design where a client would first hit the load balancer which would redirect our request to the appropriate application server based on the RR stateless algorithm.
The application server would first check if the url is present in our in-memory cache (which we would know based on the cache server id based on the cache client daemon running on the application server which uses consistent hashing to determine which cache server to check. Cache is LRU
If we get the hit, we return right there. Else, we would want to check out the database. (Key-value store). NoSQL database would be able to route the request to the correct partition and return the request. If not present, we return 404.
Overall, I am okay if immediately after the resource is added, it takes a while for it to be fully propagated to all replicas (eventual consistency is OK). However, we do want to keep durability (making sure we don't lose the write request) and latency (making redirect as quickly as possible <20ms)
The writing flow is similar but with some details explained below.
Deep dive into 2-3 key components. Explain how they work, how they scale, discuss tradeoffs, capacity, and any relevant algorithms or data structures.