Requirements
Functional Requirements:
List the key functional requirements for the system (Ask the AI for hints if stuck)...
- Create a paste with a set time to live value
- Update a paste
- Delete a paste
- Get a single paste and share that using the pasteId (random uuid)
- A user should be able to create multiple pastes
Non-Functional Requirements:
List the key non-functional requirements (performance, scalability, reliability, etc.)...
- 10 million users should be able to create paste at once
- Multiple users able to view a single paste
- Anonymous pastes viewing so no need for authentication or user sign in
- Caching should be added for the pastes
- Pastes expiration should be able to happen
API Design
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...
- POST /paste- To submit a paste
- Payload {id, content, timetolive, createdAt}
- Return
- 200 - when successfull
- 400 - when invalid payload is passed
- 500 - backend failure
- GET /paste/id - Get single paste
- Return
- 200 - when successful
- 404 - paste not found
- 429- rate limiting
- 500 - backend failure
- Return
- PUT /paste/id - Update single paste
- Payload {content, timetolive, updatedAt}
- Return
- 200 - when successful
- 404 - paste not found
- 500 - backend failure
- DELETE /paste/id - Delete single paste
- Return
- 200 - when successful
- 404 - paste not found
- 500 - backend failure
- Return
High-Level Design
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.
- A paste microservice formed with 4 lambdas for all 4 endpoints. The lambdas scale to meet demand
- A dynamodb table to store the pastes and other meta data
Detailed Component Design
Deep dive into 2-3 key components. Explain how they work, how they scale, discuss tradeoffs, capacity, and any relevant algorithms or data structures.
Latency
- Fast lambdas with concurrency can help reduce latency and aid scalability
- Can use memecached or redis store as opposed to a database like NoSQL as that is faster
Scalability
- We configure the lambda concurrency settings for scalability. This helps with horizontal scalability
- We can use read replica to improve read performance as it scales
- Possibly database sharding to improve write as well
Performance
- We make sure the performance is always maintained with an availability SLO of 99.99%
Rate limiting
- if the api becomes hit too much we could add an SQS between the apigateway and the microservices
- Or we could configure apigateway throttling with usage plans
- Error response we also return a correlationId so errors can be traced
Database
- A NoSQL database since we wont have a complex query and we arent concerned with ACID compliance
- We could either use dynamodb or a Caching store
- For concurrent updates to the same row we would use optimistic low locking because performance is more important than updates
- We could add a global secondary index
- Expired pastes would be removed using a timetolive value which would delete them from the table
Cache
- We could use a write through caching mechanism that updates the cache when we save to DB
- The cache would be configured on the GET all workouts or the GET single workout
- We could use Redis or Memecache or configure caching on the api gateway
Resliency & Fault tolerance
- We would use trycatch inside every lambda and push to a DLQ as a circuit breaker when an error occurs
- We would then configure automatic redrive between the DLQ and the lambda
Reliability
- We could add monitoring to make sure the system is always working
Monitoring and observability
- We could add monitoring via Cloudwatch logs and setup alarms against apigateway response times or messages in DLQ
Security
- Cognito is used to make sure the right users have access and the claims from cognito is used to ensure authoriation
- We can use the authorization and the claims to make sure pastes are only accessible by users they are meant for
- Could use a WAF rule & AWS Shield
Documentation
- We could use openapi spec to document the apis
Testing
- We could use unit tests on functions, integration tests between services and load testing across the entire service