I prefer to use a REST API for this Short URL service, because it fits the standard HTTP notation well (forward, create, update and delete).
createURL()
resolveURL()
listMyURLs()
updateURL()
deleteURL()
login() and logout() as usual
The User Database is only accessed at URL creation and alteration, so I choose to use a relational database for this.
As PostgreSQL is widely adopted I choose this to store my users.
The database layout may be
Usertable
The requirements for the URL table differ mostly in terms of scalability. It is read often and written to seldom.
For the simple key value manner of URLs, I choose to use Dynamo DB with the following design:
To reduce the database load in reading operations, I will use a Redis Cache with LRU strategy in between database and cache.
Because we have a service that is accessible to everyone on the internet, I recommend using an API Gateway to ratelimit if necessary.
This Gateway can do path-based-routing to either url creation or the loadbalancer for resolving.
The URL creation service can handle logins, because it uses the user database and can write to the url database.
The URL resolving service will endure high load, so I recommend scaling it with a loadbalancer.
For less database queries we should also use a cache that stores lastly used urls.
The resolving service can use the write-through strategy for that problem, meaning it searches first in cache, and only on a cache miss in db to cache it then for next time.
For handling of proper URL expiration, I would use a seperate service, that periodicly filters the database for expiring URLs to disable them. The URL TTL in cache should never be longer than expire time in DB to neglect this check.
Flow of URL resolving
Flow of URL creation
The Loadbalancer before URL resolver service should scale the url resolver when traffic increases.
Our caching strategy to use write-through caching is a common trade off, that reduces cache memory space but increases latency for seldom accessed URLs. We could cache instead all URLs with caching warming but have to pay a bigger memory bill.
If our URL creation service gets to much load, we would overwhelm the url database with write operations and may slow down reads of uncached URLs for resolving.
in the future, we could build more analytics for the users, to see informations about the resolved urls.
We could keep track of datetime, useragent, IP address and Geo information to show them to a user.
This should be done in an asynchronous manner.
We could also build a premium plan, that enables the user to create custom URLs.