Introduction to MongoDB and Helidon
Rate this quickstart
This tutorial will guide you through creating a Java application using MongoDB and Helidon. Helidon is an open-source framework designed to develop lightweight microservices in the cloud. It features a powerful and fast web core supported by Java virtual threads, providing a solid foundation for modern applications. By following a few simple steps, you will learn how to set up a Java application that seamlessly integrates with MongoDB, enabling you to concentrate on building scalable, high-performance services effortlessly.
1 git clone git@github.com:soujava/helidon-mongodb-introduction.git
For this tutorial, you’ll need:
- Java 21.
- Maven.
- A MongoDB cluster.
- MongoDB Atlas (Option 1)
- Docker (Option 2)
You can use the following Docker command to start a standalone MongoDB instance:
1 docker run --rm -d --name mongodb-instance -p 27017:27017 mongo
- At Flavor, select Helidon MP and Next.
- At application type, select Quickstart.
- At Media Support, select JSON-B.
- Define the groupId, artifactId, version, and package name as desired.
- Configure your project by selecting the desired options, such as the group and artifact ID.
- Generate the project, download the ZIP file, and extract it to your preferred location. Remember that the file structure may vary with different Helidon versions, but this should be fine for the tutorial. The core focus will be modifying the `pom.xml` file and source code, which remains relatively consistent across versions. Any minor structural differences should be good for your progress, and you can refer to version-specific documentation if needed for a seamless learning experience.
1 <dependency> 2 <groupId>org.eclipse.jnosql.databases</groupId> 3 <artifactId>jnosql-mongodb</artifactId> 4 <version>1.1.2</version> 5 </dependency>
At this point, your
pom.xml
file should look like this:1 <?xml version="1.0" encoding="UTF-8"?> 2 <project xmlns="http://maven.apache.org/POM/4.0.0" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> 5 <modelVersion>4.0.0</modelVersion> 6 <parent> 7 <groupId>io.helidon.applications</groupId> 8 <artifactId>helidon-mp</artifactId> 9 <version>4.1.1</version> 10 <relativePath/> 11 </parent> 12 <groupId>expert.os.samples</groupId> 13 <artifactId>intro-helidon-mongodb</artifactId> 14 <version>0.0.1</version> 15 16 17 <dependencies> 18 <dependency> 19 <groupId>org.eclipse.jnosql.databases</groupId> 20 <artifactId>jnosql-mongodb</artifactId> 21 <version>1.1.2</version> 22 </dependency> 23 <dependency> 24 <groupId>io.helidon.microprofile.bundles</groupId> 25 <artifactId>helidon-microprofile-core</artifactId> 26 </dependency> 27 <dependency> 28 <groupId>io.helidon.microprofile.openapi</groupId> 29 <artifactId>helidon-microprofile-openapi</artifactId> 30 </dependency> 31 <dependency> 32 <groupId>io.helidon.microprofile.health</groupId> 33 <artifactId>helidon-microprofile-health</artifactId> 34 </dependency> 35 <dependency> 36 <groupId>jakarta.json.bind</groupId> 37 <artifactId>jakarta.json.bind-api</artifactId> 38 </dependency> 39 <dependency> 40 <groupId>org.glassfish.jersey.media</groupId> 41 <artifactId>jersey-media-json-binding</artifactId> 42 <scope>runtime</scope> 43 </dependency> 44 <dependency> 45 <groupId>io.helidon.logging</groupId> 46 <artifactId>helidon-logging-jul</artifactId> 47 <scope>runtime</scope> 48 </dependency> 49 <dependency> 50 <groupId>io.smallrye</groupId> 51 <artifactId>jandex</artifactId> 52 <scope>runtime</scope> 53 </dependency> 54 <dependency> 55 <groupId>org.eclipse.microprofile.metrics</groupId> 56 <artifactId>microprofile-metrics-api</artifactId> 57 </dependency> 58 <dependency> 59 <groupId>io.helidon.microprofile.metrics</groupId> 60 <artifactId>helidon-microprofile-metrics</artifactId> 61 </dependency> 62 <dependency> 63 <groupId>org.junit.jupiter</groupId> 64 <artifactId>junit-jupiter-api</artifactId> 65 <scope>test</scope> 66 </dependency> 67 <dependency> 68 <groupId>io.helidon.microprofile.testing</groupId> 69 <artifactId>helidon-microprofile-testing-junit5</artifactId> 70 <scope>test</scope> 71 </dependency> 72 <dependency> 73 <groupId>org.hamcrest</groupId> 74 <artifactId>hamcrest-all</artifactId> 75 <scope>test</scope> 76 </dependency> 77 </dependencies> 78 79 <build> 80 <plugins> 81 <plugin> 82 <groupId>org.apache.maven.plugins</groupId> 83 <artifactId>maven-dependency-plugin</artifactId> 84 <executions> 85 <execution> 86 <id>copy-libs</id> 87 </execution> 88 </executions> 89 </plugin> 90 <plugin> 91 <groupId>io.smallrye</groupId> 92 <artifactId>jandex-maven-plugin</artifactId> 93 <executions> 94 <execution> 95 <id>make-index</id> 96 </execution> 97 </executions> 98 </plugin> 99 </plugins> 100 </build> 101 </project>
We will be using the newest version of Helidon with Eclipse JNoSQL. This integration can be done quickly because both are based on the Java Enterprise specification, Jakarta. Helidon uses Eclipse Microprofile, which incorporates several Jakarta Specifications like CDI. Eclipse JNoSQL serves as the foundation, implementing both Jakarta EE specifications for NoSQL and data.
Before starting the implementation, it's essential to configure your MongoDB database properly. In MongoDB, you must often set up credentials and specific configurations to connect to your database instance. Eclipse JNoSQL offers a flexible configuration mechanism that enables you to manage these settings effectively.
The Eclipse JNoSQL GitHub repository contains detailed configurations and setups for various databases, including MongoDB.
Configure the database name and properties in the src/main/resources/META-INF/microprofile-config.properties file to run your application locally. Open this file and add the following line to specify the database name:
1 # configure the MongoDB client for a replica set of two nodes 2 quarkus.mongodb.connection-string=mongodb://localhost 3 4 # mandatory if you don't specify the name of the database 5 jnosql.document.database=tools
This configuration will enable your application to:
- Use the “tools” database.
- Connect to the MongoDB cluster available at the provided connection string.
Enable access control and enforce authentication in production. For more details, see the security checklist.
It's important to note that Eclipse JNoSQL uses Eclipse MicroProfile Configuration to simplify the development of 12-factor applications, particularly in managing configurations. This allows you to override properties using environment variables, seamlessly switching between different configurations for development, testing, and production without modifying your code. This flexibility is a valuable aspect of creating resilient and easily deployable applications.
Now that your database is configured, you can proceed with the tutorial and create your RESTful API with Helidon and Eclipse JNoSQL for MongoDB.
In this step, we will create a simple `Tool`entity which will have four attributes:
- Name: The name of the tool (e.g., Hammer, Screwdriver)
- Type: The type or category the tool belongs to (e.g., Hand Tools, Power Tools)
- SKU: A unique identifier for the tool (Stock Keeping Unit)
- Quantity: The number of units of that tool available in the warehouse
Create a new class in the `src/main/java` directory named `Tool`.
1 import jakarta.nosql.Column; 2 import jakarta.nosql.Entity; 3 import jakarta.nosql.Id; 4 5 6 public record Tool ( String sku, String name, String type, int quantity) 7 { }
Create a tool repository
After creating the Tool entity, the next step is to define the communication interface to the database; in this sample, we will use the Jakarta Data specification's repository interfaces, which allow a single interface that will enable interactions with a database that supports both relational databases, using Jakarta Persistence, and NoSQL databases, using Jakarta NoSQL.
This ToolRepository, once extended to the `BasicRepository`, allows several database operations, such as save, find, and method by the query.
1 import jakarta.data.repository.BasicRepository; 2 import jakarta.data.repository.Repository; 3 4 5 public interface ToolRepository extends BasicRepository<Tool, String> { 6 }
Now, let’s create a RESTful API to manage developer records. Create a new class in `src/main/java` named `ToolResource`.
1 import jakarta.data.Direction; 2 import jakarta.data.Order; 3 import jakarta.data.Sort; 4 import jakarta.data.page.PageRequest; 5 import jakarta.inject.Inject; 6 import jakarta.ws.rs.Consumes; 7 import jakarta.ws.rs.DELETE; 8 import jakarta.ws.rs.DefaultValue; 9 import jakarta.ws.rs.GET; 10 import jakarta.ws.rs.POST; 11 import jakarta.ws.rs.Path; 12 import jakarta.ws.rs.PathParam; 13 import jakarta.ws.rs.Produces; 14 import jakarta.ws.rs.QueryParam; 15 import jakarta.ws.rs.WebApplicationException; 16 import jakarta.ws.rs.core.MediaType; 17 import jakarta.ws.rs.core.Response; 18 19 import java.util.List; 20 import java.util.logging.Logger; 21 22 23 24 25 public class ToolResource { 26 27 private static final Logger LOGGER = Logger.getLogger(ToolResource.class.getName()); 28 29 private final ToolRepository toolRepository; 30 31 32 public ToolResource(ToolRepository toolRepository) { 33 this.toolRepository = toolRepository; 34 } 35 36 37 38 public List<Tool> findAllTools( long page, 39 int size, 40 String order, 41 Direction direction) { 42 43 LOGGER.info("Find all tools, page: " + page + ", size: " + size + ", order: " + order + ", direction: " + direction); 44 var pageRequest = PageRequest.ofPage(page).size(size); 45 return toolRepository.findAll(pageRequest, Order.by(Sort.of(order, direction, false))).content(); 46 } 47 48 49 public void save(Tool tool) { 50 LOGGER.info("Save tool: " + tool); 51 toolRepository.save(tool); 52 } 53 54 55 56 public Tool findById( String id) { 57 LOGGER.info("Find tool by id: " + id); 58 return toolRepository.findById(id).orElseThrow(() -> new WebApplicationException("Tool not found", Response.Status.NOT_FOUND)); 59 } 60 61 62 63 public void deleteById( String id) { 64 LOGGER.info("Delete tool by id: " + id); 65 toolRepository.deleteById(id); 66 } 67 68 69 }
Now that we have created our RESTful API for managing developer records, it is time to test it. We will show how to interact with the API using various HTTP requests and command-line tools.
Initiate the project:
1 mvn package 2 java -jar target/intro-helidon-mongodb.jar
We will use `curl` to learn more about pagination using the URLs provided. It is a command-line tool that is often used to send HTTP requests. The URLs you have been given are used to access a REST API endpoint fetching fruit pages using offset pagination. Each URL requests a different page, enabling us to observe how pagination functions via the API. Below is how you can interact with these endpoints using the `curl` tool:
Inserting data
This command will generate 10 tools in the database:
This command will generate 10 tools in the database:
1 curl -X POST http://localhost:8080/tools -H "Content-Type: application/json" -d '{"sku": "SKU006", "name": "Pliers", "type": "Hand Tools", "quantity": 75}' 2 curl -X POST http://localhost:8080/tools -H "Content-Type: application/json" -d '{"sku": "SKU007", "name": "Cordless Screwdriver", "type": "Power Tools", "quantity": 50}' 3 curl -X POST http://localhost:8080/tools -H "Content-Type: application/json" -d '{"sku": "SKU008", "name": "Chisel", "type": "Hand Tools", "quantity": 90}' 4 curl -X POST http://localhost:8080/tools -H "Content-Type: application/json" -d '{"sku": "SKU009", "name": "Power Drill", "type": "Power Tools", "quantity": 60}' 5 curl -X POST http://localhost:8080/tools -H "Content-Type: application/json" -d '{"sku": "SKU010", "name": "Tape Measure", "type": "Measuring Tools", "quantity": 120}' 6 curl -X POST http://localhost:8080/tools -H "Content-Type: application/json" -d '{"sku": "SKU011", "name": "Level", "type": "Measuring Tools", "quantity": 45}' 7 curl -X POST http://localhost:8080/tools -H "Content-Type: application/json" -d '{"sku": "SKU012", "name": "Wrench Set", "type": "Hand Tools", "quantity": 30}' 8 curl -X POST http://localhost:8080/tools -H "Content-Type: application/json" -d '{"sku": "SKU013", "name": "Circular Saw", "type": "Power Tools", "quantity": 20}' 9 curl -X POST http://localhost:8080/tools -H "Content-Type: application/json" -d '{"sku": "SKU014", "name": "Angle Grinder", "type": "Power Tools", "quantity": 35}' 10 curl -X POST http://localhost:8080/tools -H "Content-Type: application/json" -d '{"sku": "SKU015", "name": "Allen Wrench", "type": "Hand Tools", "quantity": 200}'
Getting an element by ID
This command allows you to find a database using the ID:
This command allows you to find a database using the ID:
1 curl --location 'http://localhost:8080/tools/SKU006'
Remove an element by ID
This command removes a tool using the ID:
This command removes a tool using the ID:
1 curl --location --request DELETE 'http://localhost:8080/tools/SKU005'
Get tools with pagination
This request allows you to search for tools using pagination, where you can define the page, size, direction, and property:
1 curl --location 'http://localhost:8080/tools/' 2 curl --location 'http://localhost:8080/tools/?page=2' 3 curl --location 'http://localhost:8080/tools/?page=3' 4 curl --location 'http://localhost:8080/tools/?size=10' 5 curl --location 'http://localhost:8080/tools/?size=10&order=name'
In this tutorial, you learned how to set up a Java application using Helidon and MongoDB, and leveraging the simplicity and power of Jakarta NoSQL. We began by generating a basic project using the Helidon Starter, configuring it to integrate with MongoDB, and building a complete tool management system. You gained practical insight into developing lightweight, scalable microservices that can efficiently interact with NoSQL databases by creating RESTful APIs, handling database entities, and implementing pagination techniques.
Following the steps outlined in this tutorial, you can expand your application to include advanced features like authentication, monitoring, and cloud deployment using MongoDB Atlas. Helidon, combined with MongoDB and Jakarta NoSQL, provides a solid framework for building modern microservices that are high-performance and developer-friendly. You can continue exploring these technologies to exploit their robust capabilities for enterprise-level applications fully.
Access the source code used in this tutorial.
References:
Top Comments in Forums
There are no comments on this article yet.