System requirements
Functional:
User to be able to reserve parking spot, extend time, cancel reservation
Parking spots will have rate depending on size (small, medium, large)
User can view available spots
In this case, user will need to input payment method every time (no automatic payment)
Non-Functional:
Available -> Users could be parking at any time
Consistent -> Cannot have any double bookings
Capacity estimation
1,500,000 per day -> 20 transactions per second
User Table:
10,000,000 users -> 400 000 000bytes -> 400 000 KB -> 400MB
Reservation Table:
20,000,000 parking spots -> 100,000,000bytes -> 100,000 KB -> 100MB
Spot to License Plate:
20,000,000 parking spots -> 220,000,000bytes ->220,000KB -> 220MB
Looking at estimations, scaling for writes and scaling to increase transactions per second wont be necessary
API design
Public Endpoints:
/GET/Price:SpotID
- return price -> rate * hours
/POST/Reservation
Body contains spotID,licensePlate
- Pay and reserve spot
- Extend spot if spot is taken and request body has same license plate
/POST/Cancel
Body contains spotID
- Cancel Reservation
/GET/Parking/SpotID
- See when parking spot expires
/GET/Lot:LotID
- Get available/unavailable parking spots in lot
Database design
Use SQL, MySQL
User Table:
First Name VARCHAR (20)
Last Name VARCHAR (20)
Reservation Table:
Parking SpotID INT (4)
LotID INT(4)
Size CHAR(1)
Reference Table for Size to Pay rate:
Size CHAR(1)
Pay Rate Float(4)
Reference Table for Spot to License Plate:
Parking SpotID INT (4)
License Plate VARCHAR(7)
High-level design
User can reserve spot, cancel reservation or extend
Extending reservation will use same endpoint as paying, if license plate matches the car that is currently parked, extend time
User can cancel reservation 24 hours in advance
Request flows
Client loads page: get spots for lot from /GET/Lot:LotID
Client gets rate for specific spot from /GET/Price:SpotID
Client reserves a spot with /POST/Reservation
Client can cancel reservation 24hours in advance with /POST/Cancel
Client can extend spot with /GET/Parking/SpotID
Request -> Gateway -> Loadbalancer -> Server -> DB -> Server -> Client
Detailed component design
Extending reservation will use same endpoint as paying, if license plate matches the car that is currently parked, extend time
Client loads page: get spots for lot from /GET/Lot:LotID
Client gets rate for specific spot from /GET/Price:SpotID
Client reserves a spot with /POST/Reservation
Client can cancel reservation 24hours in advance with /POST/Cancel
Client can extend spot with /GET/Parking/SpotID
Request -> Gateway -> Loadbalancer -> Server -> DB -> Server -> Clien
Implement Stripe/Visa for payment, note that retries should be handled on their side
If transaction fails, send response back to user
- Check if failure is on us, if it is retry 2 more times, if failure is from payment, send failure response right away
Note that failed payment will create failure response
Trade offs/Tech choices
Use SQL (MySQL), strong relationships between rows
Failure scenarios/bottlenecks
Spike in requests during peak hours, for example people need to park and pay in the morning to get to work
- Can shard database by region/province
- Load balancer will direct request to correct DB
- Have Active/Passive load balancer to avoid single point of failure
- Can have a replication of each DB to avoid having single point of failure in DB (Master/Slave and elect slave as master if master is down)
Future improvements
Create new features depending on what customers want