System requirements
Functional:
create a endpoint that will take a url as parameter and will generate a alias
create a endpoint that will get a alias and will redirect the user for the original url
Non-Functional:
High available
The alias should be short and readable at most 7 characters long
The services need to scale
The service needs to be fault tolerant
Non predictable alias, I would use a base 32 hash function that will generate the code for based in a integer number what would lide us to 7 ** 32 possible combinations that is enough for this application
Capacity estimation
Estimate the scale of the system you are going to design.
1 million of request per day
with a scale of 1/10 which for each 10 request one is a write and 9 are read requests.
1 million / 10 = 100 thousands
100 thousands of writes request per day
900 thousands of reads per day
1 million req / 24 / 60 / 60 = ~10rps
lets say we gonna 5kb of data per write request
so in one day we gonna use ~500mb of data per day
500mb * 30 days = 15gb per month
15 * 12 = 180gb per year of data
API design
Define what APIs are expected from the system...
it will create the alias
POST api/v1/alias
{ url: string }
it redirect the user for the origin url
GET /$alias
status code 302
Database design
Defining the system data model early on will clarify how data will flow among different components of the system. Also you could draw an ER diagram using the diagramming tool to enhance your design...
We gonna have a single table
table: alias
fields:
alias: varchar
url: varchar
High-level design
You should identify enough components that are needed to solve the actual problem from end to end. Also remember to draw a block diagram using the diagramming tool to augment your design...
we gonna serve this data using a rest api,
the first layer of the architecture is api getaway it will be the only service exposed to the internet, also will have some configurations as rate limit to prevent attacks, TLS, to ensure security on the request also it will act as a load balance to distribute the load between services
the second layer will be a api service running the application that could scale horizontally.
for the database I will user dynamo db because the data model is simple and does not need a relational database, also dynamo db scales easily out of the box and cheap.
to increase the response time I also would include a cache between the api and the database using LRU strategy
how we gonna have many different apis running horizontally and the alias generate with be encoded based in sequential key I would also include zookeeper to serve this alias acros all service.
Request flows
Explain how the request flows from end to end in your high level design. Also you could draw a sequence diagram using the diagramming tool to enhance your explanation...
flow 1:
- the user provides the url on the frontend
- the frontend requests the api gateway
- the api gateway will redirect the request to the api
- the api will request a new alias to zookeeper
- the api will store the url and the alias on the dynamo db
- the api will return a 201 status code with the data created
flow 2:
- the user types on the browser the domain with the alias create
- the api gateway handle that and send a request to api
- the api try to fetch the original url from the cache, if is not there it fetches from the database
- the api redirects the user for the original url
- if the alias is not there it return a 404 status code
Detailed component design
Dig deeper into 2-3 components and explain in detail how they work. For example, how well does each component scale? Any relevant algorithm or data structure you like to use for a component? Also you could draw a diagram using the diagramming tool to enhance your design...
Trade offs/Tech choices
Explain any trade offs you have made and why you made certain tech choices...
Failure scenarios/bottlenecks
Try to discuss as many failure scenarios/bottlenecks as possible.
Future improvements
What are some future improvements you would make? How would you mitigate the failure scenario(s) you described above?