High-Level Design
First we need a client, let's choose a web-app in this case.
We then need an API gateway. This will confirm whether the user is authorized for our POST request. It will also handle caching for the GET requests. It will also handle rate-limiting overall.
Next, we need a link service, that handles the link creation and the logic around max length, characters, aliases, etc.
- If no preferences are given, We generate a UUID and Base62-encode its bytes to produce a compact, URL-safe code. This should reduce collisions.
- If an alias is given, we check the DB if the alias is already present in any link object. This will be a hash-lookup, with the key being "alias"
- If any preferences are given, we will include them, check if the short url is available, and append a random character set if its not to accomodate the user's request.
- There will be a slight variance in short link length, to increase the likelihood of generating a unique link on first try (unless the user specifies a max length)
We need a redirect service, that will fetch the redirect url, given a short url.
- this doesn't require auth, because this happens anytime someone accesses our short link.
- latency is a priority here, there should be no noticeable delay
We then need a DB to hold all our Link objects, which the link servers communicates with.
- the short_url field should have a unique constraint, so that if concurrent requests are being processed (on one service or replicas of the create link service), we can handle collisions effectively. We'll have a retry mechanism in the create link service that will keep retrying to create a short-link until a unique one is created.