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.
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.
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
-
Spring BootWeb Java application that exposes a REST API to manage products. Product information is stored inElasticsearch.product-apiusesSpring Data Elasticsearchto persist/query/delete data inElasticsearch. -
Spring BootWeb application that was implemented usingThymeleafas HTML template. Also, it usesHttp Interfacesto simplify HTTP remote access toproduct-api.
-
Open a terminal and navigate to the
springboot-elasticsearch-thymeleafroot folder and run:docker compose up -d
-
Wait for
ElasticsearchDocker container to be up and running. To verify it, run:docker ps -a
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
ElasticsearchAPI, refer to Creating indexes, alias and reindexing using Elasticsearch API.
-
In a terminal, make sure you are in the
springboot-elasticsearch-thymeleafroot folder. -
Run the following script to create the index
ecommerce.products.v1with the aliasecommerce.products(you can use the default values by just pressingEnteron every user input):./create-index.sh
-
If you want to insert some products, run:
./insert-products.sh
-
If you want to fix the
referenceproperty 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.
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"
-
In a terminal and inside the
springboot-elasticsearch-thymeleafroot folder, run the following script:./build-docker-images.sh
-
- product-api
Environment Variable Description ELASTICSEARCH_URISSpecify URIs of the Elasticsearchsearch engine to use (defaultlocalhost:9200)- product-ui
Environment Variable Description PRODUCT_API_URLSpecify URL of the product-apiservice to use (defaulthttp://localhost:8080) -
In a terminal and inside the
springboot-elasticsearch-thymeleafroot folder, run the following script:./start-apps.sh
| Application | URL |
|---|---|
| product-api | http://localhost:8080/swagger-ui.html |
| product-ui | http://localhost:9080 |
Below is a simple demo showing a user interacting with product-ui
-
To stop applications:
- If they were started with
Maven, go toproduct-apiandproduct-uiterminals and pressCtrl+C. - If they were started as Docker containers, go to a terminal and, inside the
springboot-elasticsearch-thymeleafroot folder, run the script below:./stop-apps.sh
- If they were started with
-
To stop and remove docker compose containers, network and volumes, go to a terminal and, inside the
springboot-elasticsearch-thymeleafroot folder, run the following command:docker compose down -v
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
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.shUses 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.
[Medium]: How I Reduce GIF and Screenshot Sizes for My Technical Articles on macOS
If you find this useful, consider buying me a coffee:
This project is licensed under the MIT License.

