Skip to content

ivangfr/springboot-elasticsearch-thymeleaf

Repository files navigation

springboot-elasticsearch-thymeleaf

License: MIT Buy Me A Coffee

The goal of this project is to implement an application called product-app. It consists of two Spring Boot services: product-api (backend) and product-ui (frontend). The data will be stored in Elasticsearch.

Proof-of-Concepts & Articles

On ivangfr.github.io, I have compiled my Proof-of-Concepts (PoCs) and articles. You can easily search for the technology you are interested in by using the filter. Who knows, perhaps I have already implemented a PoC or written an article about what you are looking for.

Additional Readings

Project Overview

flowchart TB
    subgraph users ["Users"]
        HTTP["REST Clients"]
        Browser["Browser"]
    end

    subgraph product-ui ["product-ui\nport 9080\n(Spring Boot Thymeleaf)"]
        UIProductController["ProductController\nMVC"]
        UIProductReviewController["ProductReviewController\nMVC"]
        ProductApiClient["ProductApiClient\n(HTTP Interface)"]
    end

    subgraph product-api ["product-api\nport 8080\n(Spring Boot REST)"]
        RestCtrl["ProductController\n/api/products"]
        ReviewCtrl["ProductReviewController\n/api/products/{id}/reviews"]
        SwaggerUI["Swagger UI"]
        ProductService["ProductService"]
        ProductRepo["ProductRepository"]
    end

    subgraph elasticsearch ["Elasticsearch"]
        db[("ecommerce.products")]
    end

    subgraph init_scripts ["Initialization Scripts"]
        CreateIndex["create-index.sh"]
        InsertProducts["insert-products.sh"]
        Reindex["reindex.sh"]
    end

    Browser -->|"HTTP"| UIProductController
    Browser -->|"HTTP"| UIProductReviewController
    Browser -->|"HTTP"| SwaggerUI

    HTTP -->|"HTTP"| RestCtrl
    HTTP -->|"HTTP"| ReviewCtrl

    UIProductController -->|"uses"| ProductApiClient
    UIProductReviewController -->|"uses"| ProductApiClient

    ProductApiClient -->|"calls"| RestCtrl
    ProductApiClient -->|"calls"| ReviewCtrl

    RestCtrl -->|"uses"| ProductService
    ReviewCtrl -->|"uses"| ProductService
    ProductService -->|"queries"| ProductRepo
    ProductRepo -->|"Spring Data ES"| db

    SwaggerUI -->|"uses"| RestCtrl
    SwaggerUI -->|"uses"| ReviewCtrl

    CreateIndex -->|"creates index/alias"| db
    InsertProducts -->|"bulk inserts"| db
    Reindex -->|"reindexes"| db
Loading

Applications

  • product-api

    Spring Boot Web Java application that exposes a REST API to manage products. Product information is stored in Elasticsearch. product-api uses Spring Data Elasticsearch to persist/query/delete data in Elasticsearch.

  • product-ui

    Spring Boot Web application that was implemented using Thymeleaf as HTML template. Also, it uses Http Interfaces to simplify HTTP remote access to product-api.

Prerequisites

Start Environment

  • Open a terminal and navigate to the springboot-elasticsearch-thymeleaf root folder and run:

    docker compose up -d
  • Wait for Elasticsearch Docker container to be up and running. To verify it, run:

    docker ps -a

Initialize Elasticsearch

Note: In the following steps, we will create an index, an alias and do a reindex using pre-defined scripts. In case you prefer to do it step-by-step calling Elasticsearch API, refer to Creating indexes, alias and reindexing using Elasticsearch API.

  • In a terminal, make sure you are in the springboot-elasticsearch-thymeleaf root folder.

  • Run the following script to create the index ecommerce.products.v1 with the alias ecommerce.products (you can use the default values by just pressing Enter on every user input):

    ./create-index.sh
  • If you want to insert some products, run:

    ./insert-products.sh
  • If you want to fix the reference property mapping error (explained below), run:

    ./reindex.sh

The script ./reindex.sh is used to reindex one index to another. The default will reindex from ecommerce.products.v1 to ecommerce.products.v2. The only difference between elasticsearch/mapping-v1.json (used by ecommerce.products.v1) and elasticsearch/mapping-v2.json (used by ecommerce.products.v2) is the type of the reference property. In the former, the type is set to text and, in the latter, to keyword.

It's interesting because the reference property has some special characters. An example of reference code is SBES@DDR4-10000. As it has the type text, Elasticsearch (using the standard analyzer) splits the content into tokens ['SBES', 'DDR4', 10000]. So, for example, if you are looking for a product with DDR4 RAM and, for some reason, the string DDR4 is present in the reference code of some product X, the product X will be selected, even if it doesn't have DDR4 in its description.

So, the script ./reindex.sh aims to fix it, setting the type keyword to the reference property. The DDR4 search issue won't happen again because, from now on, Elasticsearch won't tokenize the content present in the reference property.

Running applications using Maven

Below are the steps to start and run the applications using Maven. We will need to open a terminal for each one. Make sure you are in the springboot-elasticsearch-thymeleaf root folder while running the commands.

  • product-api

    ./mvnw clean spring-boot:run --projects product-api
  • product-ui

    ./mvnw clean spring-boot:run --projects product-ui -Dspring-boot.run.jvmArguments="-Dserver.port=9080"

Running applications as Docker containers

  • Build Docker Images

    In a terminal and inside the springboot-elasticsearch-thymeleaf root folder, run the following script:

    ./build-docker-images.sh
  • Environment Variables

    • product-api
    Environment Variable Description
    ELASTICSEARCH_URIS Specify URIs of the Elasticsearch search engine to use (default localhost:9200)
    • product-ui
    Environment Variable Description
    PRODUCT_API_URL Specify URL of the product-api service to use (default http://localhost:8080)
  • Run Docker containers

    In a terminal and inside the springboot-elasticsearch-thymeleaf root folder, run the following script:

    ./start-apps.sh

Application's URL

Application URL
product-api http://localhost:8080/swagger-ui.html
product-ui http://localhost:9080

Demo

Below is a simple demo showing a user interacting with product-ui

demo

Shutdown

  • To stop applications:

    • If they were started with Maven, go to product-api and product-ui terminals and press Ctrl+C.
    • If they were started as Docker containers, go to a terminal and, inside the springboot-elasticsearch-thymeleaf root folder, run the script below:
      ./stop-apps.sh
  • To stop and remove docker compose containers, network and volumes, go to a terminal and, inside the springboot-elasticsearch-thymeleaf root folder, run the following command:

    docker compose down -v

Running Tests

In a terminal, make sure you are inside the springboot-elasticsearch-thymeleaf root folder:

  • product-api

    ./mvnw clean test --projects product-api
  • product-ui

    ./mvnw clean test --projects product-ui

Cleanup

To remove the Docker images created by this project, go to a terminal and, inside the springboot-elasticsearch-thymeleaf root folder, run the script below:

./remove-docker-images.sh

Code Formatting

Uses Spotless Maven Plugin + Google Java Format (Java) and Prettier (JS/HTML) for automated formatting.

  • Check formatting:

    ./mvnw spotless:check
  • Auto-fix formatting:

    ./mvnw spotless:apply

Formatting is enforced automatically during ./mvnw verify.

How to optimize the GIF in the documentation folder

[Medium]: How I Reduce GIF and Screenshot Sizes for My Technical Articles on macOS

Support

If you find this useful, consider buying me a coffee:

Buy Me A Coffee

License

This project is licensed under the MIT License.

About

The goal of this project is to implement an application called product-app. It consists of two Spring Boot services: product-api (backend) and product-ui (frontend). Data will be stored in Elasticsearch

Topics

Resources

License

Stars

16 stars

Watchers

1 watching

Forks

Releases

No releases published

Sponsor this project

  •  

Packages

 
 
 

Contributors