My Solution for Design a Hotel Booking Service with Score: 5/10

by pulse_drift615

System requirements


Functional:

  1. Search and Filtering: Users need to be able to search for hotels based on various criteria such as location, price range, amenities, star rating, and availability. This functionality should allow for multi-faceted filtering to help users find the accommodations that best meet their needs.
  2. Real-time Availability and Booking: The system should provide real-time updates on hotel availability, ensuring that users can see up-to-date information on room availability before making a booking. This includes the ability to hold or reserve rooms temporarily while users complete their booking.
  3. Secure Payment Processing: Implementing a secure payment gateway is crucial for processing bookings. The system should handle various payment methods, ensure compliance with security standards (like PCI DSS), and provide users with a smooth and secure transaction process.




Non-Functional:

  • System should be highly available for users to book and browse. Uptime 99.99%
  • We should handle spikes in usage, e.g. around the holidays
  • We need strong consistency in terms of not double-booking rooms, and showing hotel availability accurately
  • Bookings should be durable - they cannot get lost.
  • System should be responsive. Queries should return in 5s. Booking should confirm in 30s.




Capacity estimation

  • 50,000 hotels
  • 1 million daily active users.
  • If each one makes one booking, we have 10 booking every second. To handle peak usage, we can design for 100 bookings every second.
  • If each user does 10 queries every day, we have 100 queries every second. To handle peak usage, we can design for 1000 queries every second.




API design


# For hotels

POST /hotel/ -> Hotel-ID

Request: Hotel-Data

Hotel-Data

  • Hotel Name
  • Description
  • Room-Groups[]

Room-Groups

  • Description
  • Count
  • Price


# For hotels

PUT /hotel/:hotel-ID

Request: Hotel-Data


GET /hotel/:hotel-ID -> Hotel-Data


POST /search/hotels?page=xxx -> HotelResult

Request: HotelQueryParams

HotelQueryParams

  • From-Date
  • To-Date
  • Clause[][] (OR of ANDs)

Clause

  • attributes-name
  • value
  • operator

HotelResult

  • HotelID[]
  • next-page.


GET hotel/:hotel-ID/occupancy?From-Date=x&To-Date=y -> HotelOccupancy

HotelOccupancy:

  • List of Occupancy-Room-Groups

Occupancy-Room-Groups:

  • RoomGroupID
  • Description
  • Count-Available
  • Count-Total
  • Price


POST /hotel/:hotel-ID/book -> BookingID

Request:

  • HotelID
  • RoomGroupID
  • From-Date
  • To-Date


POST /hotel/:hotel-ID/cancel -> True/False

Request:

  • BookingID


# For users

GET /hotel/bookings -> UserBooking[]

UserBooking

  • HotelID
  • RoomGroupID
  • BookingID
  • From-Date
  • To-Date



# For hotels

GET /hotel/:hotel-ID/bookings -> HotelBooking[]

HotelBooking

  • UserID
  • HotelID
  • RoomGroupID
  • BookingID
  • From-Date
  • To-Date



Database design


Use Postgres


Hotel:

  • Hotel-ID (primary-Key)
  • Description (create full-text index)
  • RoomRate[]

RoomRate

  • Hotel-ID
  • Room-Rate-ID (primary-key)
  • Rate ($)
  • Room-ID[]

Room

  • Room-ID (primary-key)
  • Hotel-ID
  • Room-Rate-ID
  • Date
  • Booking-ID

User

  • User-ID (primary-key)
  • Payment-Data
  • Booking[]

Booking

  • Booking-ID (primary-key)
  • Room-Rate-ID
  • Hotel-ID
  • State (created/paid/cancelled/checked-in)
  • From-Date
  • To-Date
  • modifiedAt


High-level design

We have two services behind the load balancer . one is the hotel service which is used to edit create and change the hotel metadata corresponding to the hotel and room rate objects. The other is the hotel service used to do the bookings.

The room objects are used to create locks in post progress to prevent double booking. There is one lock for every room for every day. We will always acquire these locks in order from earliest day to later day to prevent dead locks.

In addition, we also want to give people a few minutes to book rooms. To achieve this, we have a redis booking cash. We create a key representing the room and date with the TTL when a user starts a booking flow. When a user confirms they want to book we extend the TTL for five minutes before we acquire the lock in postgres.






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...






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?