Functional Requirements
Non-functional Requirements
| API | Params / Request Body | Description |
|---|---|---|
| GET /hotels | checkin_date, checkout_date, location | Get a list of hotels matching the search criteria. The minimum criteria usually includes a check-in date, a check-out date, and a location. It may also be necessary to filter by price or hotel stars depending on the requirements. |
| GET /hotel/:hotel_id | Get details about a hotel with a unique hotel_id. | |
| POST /hotels | name, location | Add a new hotel or franchise location to the existing database of hotels. Some basic info to include would be the hotel name and location (hotel admin only) |
| PUT /hotels/:hotel_id | name, location - all optional | Update hotel information for a given hotel_id. The name and location are all possible fields to update. (hotel admin only) |
| DELETE /hotels/:hotel_id | Delete an existing hotel. (hotel admin only) |
| API | Params / Request Body | Description |
|---|---|---|
| GET /hotels/:hotel_id/rooms | checkin_date, checkout_date | Get the list of rooms available for reservation in a hotel, given the hotel_id, check-in date, and check-out date. |
| GET /hotels/:hotel_id/rooms/:room_id | Get details about a specific room, given the hotel_id and room_id. | |
| POST /hotels/:hotel_id/rooms | type, prices | Add a room to a hotel, given the hotel_id. Some important data to include for a room is its type and the prices on different days. (hotel admin only) |
| PUT /hotels/:hotel_id/rooms/:room_id | Update room information for a given hotel_id and room_id. (hotel admin only) | |
| DELETE /hotels/:hotel_id/rooms/:room_id | Delete an existing hotel room. (hotel admin only) |
| API | Params / Request Body | Description |
|---|---|---|
| GET /reservations | user_id, date (optional) | Get the list of reservations for a given user, or the user's history of reservations up to a certain date. |
| GET /reservations/:reservation_id | Get details about a reservation, given its unique reservation_id. | |
| POST /reservations | reservation info | Make a new reservation, with the request body containing relevant info needed for making a reservation, such as customer information and room information. |
| DELETE /reservations/:reservation_id | Delete an existing reservation. |
| Hotel Object |
|---|
| hotel_id: string - PK |
| name: string |
| location: string |
| RoomType Object |
|---|
| room_type_id: string - PK |
| hotel_id: string |
| type: string |
| rate: integer |
| RoomTypeInventory Object |
|---|
| hotel_id: string - PK |
| room_type_id: string - PK |
| date: datetime |
| total_inventory: integer |
| total_reserved: integer |
| Room Object |
|---|
| room_id: string - PK |
| hotel_id: string |
| room_type_id: string |
| number: integer |
| Reservation Object |
|---|
| reservation_id: string - PK |
| room_type_id: string |
| guest_id: string |
| start_date: datetime |
| end_date: datetime |
| room_id: string (optional) |
| Guest Object |
|---|
| guest_id: string - PK |
| first_name: string |
| last_name: string |
| email: string |
| phone: string |
How do we check whether or not a room is available?
This is the purpose of the RoomTypeInventory Table. It allows for quick queries when checking for room availability. The alternative is to query the Reservation Table by room_type_id and count the number of reservations that fall within a specific date range, which can become slow and expensive to query for at scale. Having one row per date would allow for simpler date range querying. Therefore for each year, each RoomType object would have 365 corresponding rows in the RoomTypeInventory Table.CHECK(total_inventory - total_reserved >= 0)
An update to RoomTypeInventory would occur during a POST /reservations request. If any update fails to meet this constraint, then the update to the corresponding RoomTypeInventory object would fail, which would make the request fail as expected.| Pessimistic Locking | Optimistic Concurrency Control | Database Constraints | |
|---|---|---|---|
| Pros | Easy to implement, avoids conflicts by serializing updates | No locking, prevents editing stale data | Easy to implement, same pros as optimistic concurrency control |
| Cons | Risk of deadlocks occurring, not scalable especially if transactions are locked for too long | Poor performance during heavy data contention (many simultaneous updates on the same resource) | Poor performance during heavy data contention, not supported by all databases |