Skip to content

1 StayBooking Introduction

1 StayBooking Introduction

Goal

  • Brief introduction of the backend of the Staybooking project
  • Create a Spring Boot project

Staybooking Backend Overview

StayBooking: An online stay rental application based on React and Spring Boot.

  • Designed and built a single page web application using React. Bootstrap the development with mature component library AntD.
  • Designed and implemented the backend services based on Spring Boot to support stay upload, delete, search and reserve functionality.
  • Used MySQL to store user-generated data, e.g. stay information and reservation history, and utilized Google Cloud Storage to store media files for the uploaded stays.
  • Created geo index by Elastic search to support geo-based stay search based on user's selected locations.
  • Implemented token-based server side user authentication based on user's selected locations
  • Deployed the backend service to Google App Engine for better scalability and reliability.

Backend Structure

graph LR
  A(Client)

    A-->B[User Registration]
    A-->C[User Authentication]
    A-->D[Stay Search]
    A-->E[Stay Management]
    A-->F[Reservation Management]
        subgraph Staybooking
        subgraph "UserRegistraiton"
    B-->G[Register as Guest]
    B-->H[Register as Host]
        end
        subgraph "UserAuthentication"
    C-->I[Authenticate as Guest]
    C-->J[Authenticate as Host]
        end
        subgraph "Search"
    D-->K[Search by Location]
    K-->L[(Elasticsearch Index)]
        end

    M-->L
            subgraph "StayManagement"
    M-->N[(Google Cloud Storage)]
    M-->O[(Google GeoLocation API)]

        E-->M[Stay Upload]
    E-->P[Stay delete by ID]
    E-->Q[Stay List by Host]
    E-->R[Stay List by ID]
     end

     subgraph "Reservation"
    F-->S[Add Reservation]
    F-->T[Delete Reservation]
    F-->U[Reservation List by Guest]
    F-->V[Reservation List by Stay]
     end
    end
    G-->W[(MySQL Database)]
    H-->W
    I-->W
    J-->W
    M-->W
    K-->W
    P-->W
    Q-->W
    R-->W
    S-->W
    T-->W
    U-->W
    V-->W

Data Model

erDiagram
    A["user"]{
        VARCHAR(255) username
        VARCHAR(255) password
        BIT enable
    }
    B["Authority"]{
        VARCHAR(255) username
        VARCHAR(255) authority
    }
    C["reservation"]{
        BIGINT id
        DATE checkin_date
        DATE checkout_date
        VARCHAR(255) user_id
        BIGINT stay_id
    }
    D["stay"]{
        BIGINT id
        VARCHAR(255) name
        VARCHAT(255) address
        INT guest_number
        VARCHAR(255) description
        VARCHAR(255) user_id
    }
    E["stay_reserved_date"]{
        DATE date
        BIGINT stay_id
    }
    F["stay_image"]{
        VARCHAR(255) url
        BIGINT stay_id
    }

    A o|--o|B: "1:1"
    A o|--|{C: "1:N"
    A o|--|{D: "1:N"
    C }|--o{D: "1:N"
    D o|--|{E: "1:N"
    D o|--|{F: "1:N"

Create New Project

  1. In Intellij, create a new project from the menu file, New, then project.

  2. Under the New Project window, select Spring Initializer from the left menu, then pick the Name, Location, Group and Artifact for your project. Then click Next.

Screenshot 2024-07-07 at 03.05.50

  1. Under the Dependencies section, you can find a lot of useful libraries, e.g. Spring Web, Spring Security, Spring JPA, etc. We'll add some of them later. For now just click Finish.

Screenshot 2024-07-07 at 03.06.45

  1. Once the project is created, run Maven install to download Spring Boot libraries

Screenshot 2024-07-07 at 03.07.44

  1. Find the StaybookingApplication class under the src/main/java directory. Run the main function and make sure there's no error.

Screenshot 2024-07-07 at 03.08.34

  1. Let's go back to the pom.xml file to check the existing setup. As you can see, the only dependency we have so far is org.springframework.boot.spring-boot-starter. But on the other side, you can see almost all the important Spring-related libraries added to your project. So instead of manually adding them one by one into your pom.xml, the Spring boot starter dependency can help you simplify your dependency management.

Screenshot 2024-07-07 at 03.11.30`Screenshot 2024-07-07 at 03.13.29

  1. Similar to the spring project, we'll follow the same MVC pattern for the backend services, so manually create controller, service, repository, and model packages under com.eve.staybooking

Screenshot 2024-07-07 at 03.17.33

<version>${project.parent.version}</version>

https://stackoverflow.com/questions/64639836/plugin-org-springframework-bootspring-boot-maven-plugin-not-found

The Model-View-Controller (MVC) pattern is a design pattern used for developing web applications. It separates an application into three main components:

Model: Represents the data and the business logic of the application. It directly manages the data, logic, and rules of the application.

View: Represents the presentation layer of the application. It displays the data from the model to the user and sends user commands to the controller.

Controller: Acts as an intermediary between the Model and the View. It listens to the input from the View, processes it (using the Model), and returns the output display to the View.

Components Explanation

  1. Model: - Manages the data and business logic. - Notifies the View of any changes to the data. - Can interact with the database (typically through a repository).
  2. Repository: - Handles data access logic. - Abstracts the data source (database, web service, etc.). - Interacts with the Model to fetch and persist data.
  3. Service: - Contains business logic. - Typically uses the repository to perform data operations. - Provides methods that the controller can call to perform operations.
  4. Controller: - Handles user input. - Calls the service to process the input. - Updates the View with the results of the service operations.

Example

Let's create a simple example of an application that manages a list of books.

Model

public class Book {
 private Long id;
 private String title;
 private String author;

 // Getters and setters
}

Repository

import java.util.List;

public interface BookRepository {
 List<Book> findAll();
 Book findById(Long id);
 void save(Book book);
 void deleteById(Long id);
}

Service

import java.util.List;

public class BookService {
 private final BookRepository bookRepository;

 public BookService(BookRepository bookRepository) {
     this.bookRepository = bookRepository;
 }

 public List<Book> getAllBooks() {
     return bookRepository.findAll();
 }

 public Book getBookById(Long id) {
     return bookRepository.findById(id);
 }

 public void addBook(Book book) {
     bookRepository.save(book);
 }

 public void deleteBook(Long id) {
     bookRepository.deleteById(id);
 }
}

Controller

import java.util.List;

public class BookController {
 private final BookService bookService;

 public BookController(BookService bookService) {
     this.bookService = bookService;
 }

 public List<Book> listBooks() {
     return bookService.getAllBooks();
 }

 public Book viewBook(Long id) {
     return bookService.getBookById(id);
 }

 public void createBook(Book book) {
     bookService.addBook(book);
 }

 public void deleteBook(Long id) {
     bookService.deleteBook(id);
 }
}

View (Simplified Example in HTML)

html
Copy code
<!DOCTYPE html>
<html>
<head>
 <title>Book List</title>
</head>
<body>
 <h1>Books</h1>
 <ul id="book-list">
     <!-- Books will be listed here -->
 </ul>
 <script>
     async function loadBooks() {
         const response = await fetch('/books');
         const books = await response.json();
         const bookList = document.getElementById('book-list');
         bookList.innerHTML = books.map(book => `<li>${book.title} by ${book.author}</li>`).join('');
     }
     loadBooks();
 </script>
</body>
</html>

How They Interact

  1. User Interaction: User interacts with the View (e.g., loads the book list page).
  2. Controller: The View sends a request to the Controller (e.g., /books).
  3. Service: The Controller calls the appropriate method in the Service (e.g., getAllBooks()).
  4. Repository: The Service interacts with the Repository to fetch data from the database.
  5. Model: The Repository returns the data to the Service, which might be in the form of Model objects.
  6. View Update: The Controller updates the View with the data from the Service.

This separation of concerns allows for more modular, testable, and maintainable code