Let me Show you the Spring Boot Backend for a Movie Search App using Elasticsearch, MinIO and MySQL
Photo by Jakob Owens on Unsplash
Heya fellows!
Today we will take a closer look at my IMDb Clone's Spring Boot Backend and how it's built up. In combination with a MySQL database, it's building the backbone of the project. The App has excellent search capabilities and provides movie images and user profile photos. I will talk about how I implemented the search engine or the file storage in later posts.
What does this project differentiate from other real-world example apps? It comes with the original IMDb dataset of ~9 million movies shipped!
Contents
1. What Functionality does this Backend provide?
Users can search for movies from the original IMDb dataset (with Elasticsearch as Search Engine and images are retrieved from MinIO)
user registration with email confirmation and JWT security
user can rate movies (CRUD with MySQL)
user can add movies to their watchlist
user can comment on movies and have conversations
and much more...
2. How to Rebuild this Project
The best way to learn is to get our hands on it. Firstly, we just have to download and build the repository:
git clone https://github.com/NiklasTiede/imdb-clone.git
Before we can run the application we have to pull and run the docker image of the database. This saves us the extra effort of adding credentials to config files, creating database schemes, importing the dataset and indexing the table.
cd infrastructure/deployment/development
docker-compose up -d
Be aware: the docker containers need 5-20 min before you can connect to them because the MySQL container has to import the data from the .csv
file first and MinIO has to load the images! You can also remove the -d
(detach) flag to see when the container is ready. Then we can load our gradle project, let it download dependencies if not already done and run it!
3. Testing some Endpoints
I added .http
-files which makes it very simple to execute requests against the endpoints! Here's an example if we want to search for a movie (substring search).
### get multiple movies by an array of ids
POST {{protocol}}{{host}}:{{port}}/api/movie/get-movies
Content-Type: application/json
{
"movieIds": [1457767]
}
We get a paged response back.
{
"content": [
{
"primaryTitle": "The Conjuring",
"originalTitle": "The Conjuring",
"startYear": 2013,
"runtimeMinutes": 112,
"modifiedAtInUtc": "2023-05-07T14:04:49Z",
"createdAtInUtc": "2023-05-07T14:04:49Z",
"movieGenre": [
"THRILLER",
"HORROR",
"MYSTERY"
],
"movieType": "MOVIE",
"imdbRating": 7.5,
"imdbRatingCount": 493920,
"adult": false,
"ratingCount": 0,
"description": "Paranormal investigators Ed and Lorraine Warren work to help a family terrorized by a dark presence in their farmhouse. Forced to confront a powerful entity, the Warrens find themselves caught in the most terrifying case of their lives.",
"imageUrlToken": "DoamaWHqAaGNIJVf4RuS1ORnTA1yzb"
}
],
"page": 0,
"size": 30,
"totalElements": 1,
"totalPages": 1,
"last": true
}
If we want to access secured endpoints we have to create an account. The first account created will automatically have Admin role permissions.
Email confirmation is not necessary, it is turned off by default. But you can activate it by setting the following property from false
to true
.
spring.mail.properties.mail.smtp.starttls.enable=false
Now we can log in.
A JSON Web Token will be returned which we then use to authenticate if necessary.
{
"accessToken": "eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiIxiwiaWF0IjoxNjY2NTQxNTEyLCJleHAiOjE2NjkxMzm1MTJ9.HKlIagNPjHH-GITb_hMzcS4bH0jSMZGrjolw_buneIpm7MIYiN-42nLMqkj7ulRYqXv4LFfWwsNEMGFIJim30w",
"tokenType": "Bearer"
}
Now let's request a secured endpoint. Only users can rate movies. So let's rate a movie.
The rating of the movie is stored in a database.
You can go on and check out also some other endpoints!
4. What's the Data Model under the Hood?
Here's a UML diagram of the underlying data model.
The two most important tables of the data model are the account
- and movie
tables. The watchlist
and rating
tables are using a composite primary key: each user can rate or put a movie on his watchlist only once. For the email confirmation and the password reset, we need a verification token which is persisted in the verification_token
table.
5. Topics to Learn from this Project
I learned a lot by writing this project. Here are some interesting topics you can find in this project.
handling Exceptions with @ControllerAdvice
mapping with Mapstruct
validation with Javax constraints
multiple Enums: Bitvalue vs. extra Table
entities based on Composite Primary Key
scheduling Jobs
spring-boot Profiles
custom Validation Annotations
Entity-Relationship Models
importing Data (CSV file) into MySQL
configure CORS Policy
column Indexing
how to run ElasticSearch queries
use MinIO for storing files
...and many more! Feel free to fork/clone the repository and discover it!
I put a lot of effort into this project and will continue working on it. The React Frontend still needs some work but I would appreciate it if you give my GitHub Repository a star! ๐
I wish you all a nice day!