Define the APIs expected from the system. This is your chance to analyze and define the read and write paths so that you can come up with the high-level design...
limitersvc - invoked by a client (potentially another API - API is checking with limitersvc that client can make requests)
input:
{
"apiKey": myAPIKey,
"request": requestType // different endpoints can have different max rate limits
}
output:
{
"apiKey": myAPIKey,
"status": success/failure
}
adminsvc
getPlanForEndpoint/thisendpoint
{
"apiKey": myAPIKey,
}
output:
{
"apiKey": myAPIKey,
"maxRequests": 3,
"minutes": 1
}
upgradePlanForEndpoint/thisendpoint - upgrading tier
{
"apiKey": myAPIKey,
"payment": cardDetails
}
output:
{
"apiKey": myAPIKey,
"maxRequests": 10,
"minutes": 1
}
cancelPlanForEndpoint/thisendpoint - upgrading tier
{
"apiKey": myAPIKey,
}
output:
{
"apiKey": myAPIKey,
"success": true
}
Describe the overall system architecture. Identify the main components needed to solve the problem end-to-end. Use the diagramming tool to create a block diagram.
Deep dive into 2-3 key components. Explain how they work, how they scale, discuss tradeoffs, capacity, and any relevant algorithms or data structures.
b. Cache key is api key + endpoint. Values are number of tokens + last refill time.
Cons: what if we receive two requests from the same API key at same millisecond, different machines? Use a locking mechanism, where one acquires a lock to write. That way we guarantee one write per key.