I anticipate that this system will have about 1000 users per month. Each user will on average need to generate about 5 shortened urls per week, or roughly 20 urls per user, equaling 20000 requests for url shortening. Assuming most of the load will happen during business hours Mon-Fri, this comes out to about 1000 requests per day.
We'll start with the following endpoints:
tables:
flowchart TD A[Client] -->|HTTP Request| B[API] B -->|Route based on Endpoint| C{Request Type} C -->|POST| D[Shorten URL Logic] D --> E[Store URL in Database] E -->|Return Shortened URL| F[API Response] C -->|GET| G[Redirect to Original URL] G -->|Get Original URL| E
The request flow is relatively straightforward. It begins with a request to the API endpoints available, particularly /get and /post. The /post endpoint invokes business logic to generate the shortened url; at the database level, there's a uniqueness constraint on the shortened_url column in a table. When attempting to write to the table with the newly shortened_url, if there's an IntegrityError, we re-generate a new shortened_url to eliminate collisions.
After the new url data is stored in the database, we return the shortened url to the client via a JSON response through our API.
The api endpoint would have three main endpoints - /post, /get/{id}, and /get to create a shortened url, get a generated url, and get all generated urls for an account, respectively. The urls would be account- and user-based for compartmentalization.
The database would consist of one main table, the urls table, with the columns and restrictions listed above (uniqueness constraint on the shortened_url column, as well as primary key based on the url_id). We would give each shortened url a default TTL of a year, with the option to extend on shorten this based on client requirements. We would then use a custom cron job to clean up expired URLs in order to reduce the likelihood of naming collisions.
Since collisions with shortened urls are unlikely to happen very often, it's not too much of a drain on the system to retry the url generation based on a database integrity error. Each db call is somewhat expensive, but it would happen very rarely.
One potential bottleneck is the issue of naming collisions if too many urls are being created at once, increasing the risk of said naming collisions. If that happens, the system would slow down because of the generation retries.
Coming up with a more flexible approach to url TTL would be nice. Additionally, we could introduce a caching mechanism in order to allow shortened urls that are accessed frequently to be easier to access and reduce the load on the system.