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
-
In Intellij, create a new project from the menu file, New, then project.
-
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.
- 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.
- Once the project is created, run Maven install to download Spring Boot libraries
- Find the StaybookingApplication class under the src/main/java directory. Run the main function and make sure there's no error.
- 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 isorg.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 yourpom.xml
, the Spring boot starter dependency can help you simplify your dependency management.
`
- 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
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
- 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).
- Repository: - Handles data access logic. - Abstracts the data source (database, web service, etc.). - Interacts with the Model to fetch and persist data.
- Service: - Contains business logic. - Typically uses the repository to perform data operations. - Provides methods that the controller can call to perform operations.
- 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
- User Interaction: User interacts with the View (e.g., loads the book list page).
- Controller: The View sends a request to the Controller (e.g.,
/books
).- Service: The Controller calls the appropriate method in the Service (e.g.,
getAllBooks()
).- Repository: The Service interacts with the Repository to fetch data from the database.
- Model: The Repository returns the data to the Service, which might be in the form of Model objects.
- 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