Building a Flight Reservation System Like Expedia

Abhishek Ranjan
7 min readMay 18, 2023

--

Introduction

A flight reservation system is an essential component of modern travel services, like Expedia, that allow users to search, compare, and book flights from various airlines. In this article, we will guide you through the process of building a flight reservation system using Java, Spring Boot, microservices architecture, Kubernetes, and Kafka for event processing.

System Overview

To create a flight reservation system with a microservices architecture, we will need to implement the following components:

  • Flight Search Service: Allows users to search for flights by providing the origin, destination, and travel dates.
  • Flight Comparison Service: Allows users to compare different flights based on factors such as price, duration, and airline.
  • Flight Booking Service: Allows users to reserve a flight and provide their personal and payment details.

Technologies and APIs

We will use the following technologies:

  • Java as the programming language
  • Spring Boot for creating the microservices
  • Spring Cloud for microservices patterns and tools
  • Kubernetes for container orchestration
  • Kafka for event processing and communication between microservices
  • Skyscanner API for searching and comparing flights
  • Stripe API for handling payments

High Level Design

This architecture leverages Google Cloud Platform’s (GCP) robust services and an open-source ELK Stack for logging and monitoring. Below, I’ll provide a detailed explanation of each component and how they interact in the context of a flight reservation system:

  1. Cloud DNS: This is GCP’s highly available and scalable Domain Name System. It translates user-friendly domain names (like www.myflights.com) into IP addresses that machines can understand. When a user makes a request to the website, it is first received by Cloud DNS.
  2. Cloud Load Balancing: After Cloud DNS resolves the domain to an IP address, the request is passed to Cloud Load Balancing. This service automatically distributes incoming user traffic across multiple targets (in this case, services within the GKE Cluster), ensuring the application has high availability and fault tolerance.
  3. GKE Cluster: This stands for Google Kubernetes Engine Cluster. It is a managed environment for deploying, scaling, and managing containerized applications. In this system, we have three main services — Flight Search Service, Flight Comparison Service, and Flight Booking Service — all running as separate deployments within the GKE Cluster.
  4. Cloud SQL: This is Google’s fully-managed relational database service. It’s used by the services in the GKE Cluster to store and retrieve data, such as flight details, booking information, and user data.
  5. Cloud Storage: This service is used for storing static assets, like images, CSS, and JavaScript files, that are required by the web application.
  6. Cloud CDN: Cloud Content Delivery Network works with Cloud Storage to deliver these static assets to users with low latency, regardless of their location.
  7. SendGrid: An external API used for sending booking confirmation emails to users.
  8. Stripe: An external API used for handling payments.
  9. GDS (Global Distribution System): An external system for searching and comparing flights. It is used by the Flight Search Service.
  10. VPC: Stands for Virtual Private Cloud. It provides an isolated network for the GKE Cluster and Cloud SQL, which enhances the security of the system by limiting access.
  11. Secret Manager: This service is used to store and access sensitive information like API keys and database credentials.
  12. Cloud Armor: This works with Cloud Load Balancing to protect the application against Distributed Denial of Service (DDoS) attacks and other web-based threats.
  13. Elasticsearch, Logstash, and Kibana (ELK Stack): This open-source suite is used for logging, monitoring, and visualizing the system’s data in real-time. Logstash collects and parses logs, Elasticsearch stores the log data, and Kibana presents the data in visualizations providing actionable insights.
  14. Pub/Sub: Google Cloud’s event-driven messaging service that enables communication between microservices. It is used to publish events from one service and subscribe to those events from another service.

This architecture is designed to be highly scalable and fault-tolerant, ensuring the system can handle a large number of users, similar to Expedia. The use of managed services like GKE and Cloud SQL means less operational overhead, allowing you to focus more on developing features for the application. The system’s security is also a priority, with measures like VPC isolation, Secret Manager for sensitive data, and Cloud Armor for threat protection.

Low-Level Design

In a microservices architecture, each service should have its own database to ensure loose coupling and service autonomy. This is commonly referred to as Database-per-service pattern.

Let’s create a database design for our flight reservation system with the services we discussed: Flight Search Service, Flight Comparison Service, and Flight Booking Service.

Here’s how our databases might look for each service:

Now moving on to details of each service

Stop 0 : User Service

Handles user-related operations (registration, login, profile management, etc.)

It will have a simple db looking like

APIs

  • POST /users : Register a new user
  • POST /users/login : Authenticate a user
  • GET /users/{userId} : Get user details
  • PUT /users/{userId} : Update user details
  • DELETE /users/{userId} : Delete a user account

Stop 1: Flight Search Service

Our first stop is the Flight Search Service, the mighty heart of our application that interacts directly with the Global Distribution System (GDS).

Here’s how it works:

  1. The user sends a search query. This can include the departure city, destination city, departure date, and return date.
  2. The Flight Search Service takes this query and makes an API call to the GDS.
  3. The GDS responds with a list of flights that match the query. Each flight includes details like the airline, flight number, departure time, arrival time, and price.
  4. The Flight Search Service then stores or caches this flight data in the database for future queries.
Database Design

APIs

  • GET /flights : Get all flights
  • GET /flights?origin={origin}&destination={destination}&date={date} : Search flights based on criteria
  • GET /flights/{flightId} : Get details of a specific flight

Stop 2: Flight Comparison Service

Next, we take a quick hop to the Flight Comparison Service. This service is like the brain of our system, doing all the heavy thinking to provide the user with the best options.

  1. The user sends a comparison query. This could be a request to sort flights by price, departure time, or duration.
  2. The Flight Comparison Service fetches the relevant flight data from the database.
  3. It then compares the flights based on the user’s preferences and produces a sorted list.
  4. This sorted list is then sent back to the user.

APIs

  • POST /compare : Compare multiple flights. The request body would include an array of flightIds to compare.
  • GET /compare/{comparisonId} : Get the comparison result

Stop 3: Flight Booking Service

Our final stop is the Flight Booking Service. This is where all the action happens — it’s like the hands of our system, grabbing hold of the user’s selected flight and making it theirs!

Here’s the play-by-play:

  1. The user sends a booking request. This includes their selected flight and payment information.
  2. The Flight Booking Service reserves the flight in the database. This involves creating a new booking record and linking it to the user’s account.
  3. Once the flight is reserved, the service processes the payment through the payment gateway.
  4. Upon successful payment, the service sends a booking confirmation email to the user.
Database Design Flight Booking Service

APIs

  • POST /bookings : Create a new booking. The request body would include userId, flightId, and details of passengers.
  • GET /bookings/{bookingId} : Get details of a specific booking
  • PUT /bookings/{bookingId} : Update a booking (e.g., for cancellations)
  • GET /users/{userId}/bookings : Get all bookings made by a specific user

And there you have it — our whistle-stop tour of the flight reservation system’s microservices design. Each service plays its unique role, working in harmony to provide a seamless experience for the user.

Notification Service

This is an anciliarry service so would not go in detail

APIs

  • POST /notifications : Create a new notification. The request body would include userId and message details.
  • GET /users/{userId}/notifications : Get all notifications for a specific user
  • PUT /notifications/{notificationId} : Update a notification’s status (e.g., mark as read)

Conclusion

In this article, we have walked you through the process of building a flight reservation system like Expedia using Java, Spring Boot, microservices architecture, Kubernetes, and Kafka for event processing. We have also illustrated the system’s structure and functionality using diagrams. While this guide provides a basic outline, you can further enhance the system by integrating additional features, such as user accounts, email notifications, and more.

🔗 Connect with me on LinkedIn!

I hope you found this article helpful! If you’re interested in learning more and staying up-to-date with my latest insights and articles, don’t hesitate to connect with me on LinkedIn.

Let’s grow our networks, engage in meaningful discussions, and share our experiences in the world of software development and beyond. Looking forward to connecting with you! 😊

Follow me on LinkedIn ➡️

--

--