Requirements


Functional Requirements:


  • Allow reservation of a parking spot.
  • Process payment for the reservation.
  • Enable parking of a car in the reserved spot.
  • Support early departure before reservation time expires.
  • Gate check-in/out.
  • Handle no show.



Non-Functional Requirements:


  • Low latency: quick payment processing
  • High availability
  • Consistency: in case of network partition successful payment still should be saved
  • Strong consistency: parking spot should not be overbooked by two different people


API Design

Core enteties:

Parking spot

user

reservations


Table USERS:

user_id[primary key]

//other metadata


Table SPOTS:

parking_id[primary key],

price,

//other metadata


Table RESERVATIONS:

reservation_id[pk]

user_id[fk]

parking_id[fk]

from

to

checkin_time

checkout_time

created_at


API:

// list of available parkings in given log

GET /parkings?from_time={from_time}&to_time={to_time}&page={page}&count={count} ->{

available_parkings[] : {

parking_id,

price

}

}


// create new reservation

POST /users/reservations->{ parking_id = {parking_id}, from={from}, to={to},

payment_details={details} } -> 201


// get all users reservations

GET /users/reservations->{

reservations_info[] : {

parking_id, from, to

}

}


// cancel reservation

DELETE /users/reservations ->{

parking_id, from, to

}


// check in user

PUT /users/check_in->{

parking_id,

checkin_time={time}

}


// check out user

PUT /users/check_out->{

parking_id,

checkout_time={time}

}


High-Level Design

  1. api requests enter api gateway
  2. application server transfer request to corresponding service:
    1. To retrieve available spots we query db: SELECT parking_id, SUM(IF(Reservation.to <= from OR Reservation.from >=to, 0, 1)) as overlap_count FROM Spots LEFT JOIN Reservations ON parking_id GROUP BY parking_id HAVING overlap_count = 0
    2. to book reservation we send request to payment service that redirects it to stripe
    3. Once payment is processed we create new record in DB
    4. to check in we check in/out reservation time and update record in reservations



Detailed Component Design

  1. to support high throuput we place LB infront of app service to distribute load
  2. to optimze storage we shard DB using user_id parking_id to grand that all requests for user will hit single shard
  3. to optimize sql queries we will introduce cache infront of DB
  4. we will use sql db
  5. LB+sharding+cache grant high availability of the service
  6. to grant strong consitency we will introduce kafka as event broker(partitioned by parking_id) for all reservation event. that will guaranty that no two users will overbook the same lot