Docs Menu
Docs Home
/ /

Integrate MongoDB with Quarkus

In this guide, you can learn how to create a Java REST API that uses Quarkus as the web framework and Eclipse JNoSQL to access MongoDB. Quarkus is an open-source Java framework designed for cloud-native microservices and serverless development. Eclipse JNOSQL implements the Jakarta NoSQL and Jakarta Data specifications to simplify the integration of Java applications with NoSQL databases.

The application in this tutorial consists of the following layers:

  • Database layer: MongoDB provides data storage and retrieval.

  • Application layer: Quarkus handles HTTP requests, routing, and dependency injection.

  • Data access layer: JNoSQL provides MongoDB document mapping and repository patterns.

This tutorial uses the Quarkus JNoSQL Extension to access MongoDB, which provides a unified API for NoSQL databases and allows you to work with MongoDB by using familiar Java patterns and annotations. As a result, you can use MongoDB and Quarkus to develop lightweight applications with minimal configuration.

By integrating MongoDB with Quarkus, you can leverage Quarkus' fast startup times and efficient resource use alongside MongoDB's flexible document model. This combination supports applications that require type safety, scalability, and rapid development cycles. You can use MongoDB and Quarkus to create real world applications such as microservices, cloud-native APIs, or systems that require high performance and low resource consumption.

This tutorial shows you how to build a REST API that uses MongoDB and Quarkus. The application accesses sample restaurant data, queries the data, and returns the results through RESTful endpoints. The tutorial also includes instructions for connecting to a MongoDB cluster hosted on MongoDB Atlas.

Tip

If you prefer to connect to MongoDB by using the Java driver without Quarkus, see the Get Started with the Java Driver tutorial.

Follow the steps in this section to install the project dependencies, create an Atlas cluster, and set up the application structure.

1

To create the Quick Start application, install the following software in your development environment:

Prerequisite
Notes

Install JDK version 21 or later.

Use version 3.8.1 or later.

This command-line interface allows you to create and manage Quarkus projects from your terminal.
Important: This tutorial uses version 3.30.6, and later versions might cause errors. Follow the installation instructions corresponding to your operating system to install the specific version.

Code editor

Use the code editor of your choice.

Terminal app and shell

For MacOS users, use Terminal or a similar app. For Windows users, use PowerShell or Command Prompt.

2

MongoDB Atlas is a fully managed cloud database service that hosts your MongoDB deployments. If you do not have a MongoDB deployment, you can create a MongoDB cluster for free by completing the MongoDB Get Started tutorial. The MongoDB Get Started tutorial also demonstrates how to load sample datasets into your cluster, including the sample_restaurants database that is used in this tutorial.

To connect to your MongoDB cluster, you must use a connection string. To learn how to retrieve your connection string, see the Add your connection string section of the MongoDB Get Started tutorial.

Important

Save your connection string in a secure location.

3

From your terminal, run the following command to create a new Quarkus project named quarkus-quickstart that configures the Quarkus JNoSQL Extension for MongoDB and JSON serialization for REST endpoints:

quarkus create app quarkus-quickstart --extensions=jnosql-mongodb,resteasy-jackson

Then, navigate to your project directory by running the following command:

cd quarkus-quickstart
4

Navigate to the src/main/resources/application.properties file and add the following configuration properties:

jnosql.document.database=sample_restaurants
quarkus.mongodb.connection-string=<connection string>

This code configures your connection to the sample_restaurants database in your MongoDB cluster. Replace the <connection string> placeholder with the connection string that you saved in a previous step.

5

The Quarkus project template includes some sample files that you can remove for this tutorial. To delete these unneeded files, select the tab corresponding to your operating system and run the following commands from your quarkus-quickstart directory:

rm src/main/java/org/acme/Car.java
rm src/main/java/org/acme/Garage.java
rm src/test/java/org/acme/GarageTest.java
rm src/main/java/org/acme/GreetingResource.java
rm src/test/java/org/acme/GreetingResourceIT.java
rm src/test/java/org/acme/GreetingResourceTest.java
del src/main/java/org/acme/Car.java
del src/main/java/org/acme/Garage.java
del src/test/java/org/acme/GarageTest.java
del src/main/java/org/acme/GreetingResource.java
del src/test/java/org/acme/GreetingResourceIT.java
del src/test/java/org/acme/GreetingResourceTest.java

After setting up the project structure and dependencies, follow the steps in this section to create your data model, repository class, and REST endpoints.

1

Create a file named Restaurant.java in the src/main/java/org/acme directory and paste the following code:

quarkus-quickstart/src/main/java/org/acme/Restaurant.java
package org.acme;
import jakarta.nosql.Column;
import jakarta.nosql.Entity;
import jakarta.nosql.Id;
/**
* Represents a restaurant entity from the sample_restaurants database .
* This class is used as an entity in the MongoDB database.
*/
@Entity("restaurants")
public class Restaurant {
@Id
private String id;
@Column
private String name;
@Column
private String borough;
@Column
private String cuisine;
// Default constructor required by JNoSQL
public Restaurant() {}
// Constructor
public Restaurant(String id, String name, String borough,String cuisine) {
this.id = id;
this.name = name;
this.borough = borough;
this.cuisine = cuisine;
}
// Getters and setters
public String getId() { return id; }
public void setId(String id) { this.id = id; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getBorough() { return borough; }
public void setBorough(String borough) { this.borough = borough; }
public String getCuisine() { return cuisine; }
public void setCuisine(String cuisine) { this.cuisine = cuisine; }
}

This file defines the Restaurant entity class, which maps to documents in the sample_restaurants.restaurants collection. The @Entity annotation marks this class as a JNoSQL entity, and the field annotations map Java properties to document fields.

2

Create a file named RestaurantRepository.java in the src/main/java/org/acme directory and paste the following code:

quarkus-quickstart/src/main/java/org/acme/RestaurantRepository.java
package org.acme;
import jakarta.data.repository.Repository;
import org.eclipse.jnosql.mapping.NoSQLRepository;
import java.util.List;
/**
* Interface for managing restaurant data.
*
* It uses the Jakarta Data Specification capabilities.
*
*/
@Repository
public interface RestaurantRepository extends NoSQLRepository<Restaurant, String> {
List<Restaurant> findByBorough(String borough);
List<Restaurant> findByCuisine(String cuisine);
}

This repository class provides methods for accessing restaurant data in MongoDB. It defines custom findByBorough() and findByCuisine() query methods, and you can also use a RestaurantRepository instance to access built-in create, read, update, and delete methods.

3

In the src/main/java/org/acme directory, create a file named RestaurantResource.java and paste the following code:

quarkus-quickstart/src/main/java/org/acme/RestaurantResource.java
package org.acme;
import jakarta.inject.Inject;
import jakarta.ws.rs.*;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;
import java.util.List;
/**
* REST API controller for restaurant operations.
* Provides endpoints for retrieving restaurant data from MongoDB.
*/
@Path("/restaurants")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public class RestaurantResource {
@Inject
RestaurantRepository restaurantRepository;
/**
* Retrieves all restaurants from the database.
*
* @return List of all restaurants
*/
@GET
public Response getAllRestaurants() {
try {
List<Restaurant> restaurants = restaurantRepository.findAll().toList();
System.out.println("Found " + restaurants.size() + " restaurants");
return Response.ok(restaurants).build();
} catch (Exception e) {
e.printStackTrace();
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
.entity("Error retrieving restaurants: " + e.getMessage())
.build();
}
}
/**
* Retrieves filtered restaurants in Queens that contain "Moon" in the name.
*
* @return List of filtered restaurants
*/
@GET
@Path("/browse")
public Response getFilteredRestaurants() {
try {
// Temporarily use findAll() to test basic connectivity
List<Restaurant> allRestaurants = restaurantRepository.findAll().toList();
System.out.println("Total restaurants found: " + allRestaurants.size());
// Filter for Queens restaurants that also have "Moon" in the name
List<Restaurant> queensRestaurants = allRestaurants.stream()
.filter(restaurant -> "Queens".equals(restaurant.getBorough()) &&
restaurant.getName() != null &&
restaurant.getName().toLowerCase().contains("moon"))
.toList();
System.out.println("Queens restaurants found: " + queensRestaurants.size());
return Response.ok(queensRestaurants).build();
} catch (Exception e) {
e.printStackTrace();
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
.entity("Error retrieving filtered restaurants: " + e.getMessage())
.build();
}
}
/**
* Retrieves restaurants by cuisine type.
*
* @param cuisine The cuisine type to filter for
* @return List of restaurants that have the specified cuisine
*/
@GET
@Path("/cuisine/{cuisine}")
public Response getRestaurantsByCuisine(@PathParam("cuisine") String cuisine) {
try {
List<Restaurant> restaurants = restaurantRepository.findByCuisine(cuisine);
return Response.ok(restaurants).build();
} catch (Exception e) {
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
.entity("Error retrieving restaurants by cuisine: " + e.getMessage())
.build();
}
}
}

This REST resource class defines the following HTTP endpoints:

  • GET /restaurants/: Retrieves all documents from the restaurants collection

  • GET /restaurants/browse: Retrieves documents that represent restaurants in Queens containing "Moon" in their name, performing a case-insenstive query

  • GET /restaurants/cuisine/{cuisine}: Retrieves documents that represent restaurants offering the specified cuisine value

4

In the src/test/java/org/acme directory, create a file named RestaurantRepositoryTest.java and paste the following code:

quarkus-quickstart/src/test/java/org/acme/RestaurantRepositoryTest.java
package org.acme;
import io.quarkus.test.junit.QuarkusTest;
import jakarta.inject.Inject;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
/**
* RestaurantRepositoryTest is a test class for testing the RestaurantRepository operations.
*
* It uses the Quarkus Test framework to test the restaurant data access.
*/
@QuarkusTest
public class RestaurantRepositoryTest {
@Inject
RestaurantRepository restaurantRepository;
@Test
@DisplayName("Should retrieve restaurants from the database")
public void testRetrieveRestaurants() {
// Test repository injection and MongoDB connection
assertThat(restaurantRepository).isNotNull();
}
@Test
@DisplayName("Should find restaurants by borough")
public void testFindRestaurantsByBorough() {
// Test that the method exists and returns data
List<Restaurant> restaurants = restaurantRepository.findByBorough("Queens");
assertThat(restaurants).isNotNull();
}
}

This file uses Quarkus's testing framework for integration testing. The code defines the following methods to test your MongoDB connection:

  • testRetrieveRestaurants(): Verifies that your RestaurantRepository class accesses MongoDB

  • testFindRestaurantsByBorough(): Verifies that the findByBorough() method retrieves MongoDB data

Finally, follow the steps in this section to run your REST API and test the endpoints by using curl commands.

1

First, run the following command from your project directory to run the test suite:

./mvnw test

This command runs the RestaurantRepositoryTest class and verifies that your application can access MongoDB data. If successful, your command output contains the following information:

[INFO] Results:
[INFO]
[INFO] Tests run: 2, Failures: 0, Errors: 0, Skipped: 0
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: ... s
[INFO] Finished at: ...
[INFO] ------------------------------------------------------------------------
2

From your project directory, run the following command to compile and start the application in development mode:

./mvnw quarkus:dev
3

In a separate terminal window, run the following curl commands to test the REST endpoints. Each endpoint returns JSON data containing restaurant information from the sample_restaurants.restaurants collection. If successful, your commands return data similar to the sample outputs.

  1. Retrieve all restaurants.

    curl http://localhost:8080/restaurants/
    [{"id":"...","name":"Morris Park Bake Shop","borough":"Bronx","cuisine":"Bakery"},
    {"id":"...","name":"Wilken'S Fine Food","borough":"Brooklyn","cuisine":"Delicatessen"},
    {"id":"...","name":"Taste The Tropics Ice Cream","borough":"Brooklyn","cuisine":"Ice Cream,
    Gelato, Yogurt, Ices"},
    {"id":"...","name":"Carvel Ice Cream","borough":"Queens","cuisine":"Ice Cream, Gelato, Yogurt,
    Ices"},
    ...]
  2. Retrieve restaurants in Queens that have "Moon" in the name.

    curl http://localhost:8080/restaurants/browse
    [{"id":"...","name":"Somoon","borough":"Queens","cuisine":"Asian"},
    {"id":"...","name":"New Moon Star Restaurant","borough":"Queens","cuisine":"Chinese"},
    {"id":"...","name":"Moon Tikka Grill","borough":"Queens","cuisine":"Indian"},
    {"id":"...","name":"Silver Moon Diner","borough":"Queens","cuisine":"American"},
    {"id":"...","name":"Mooney'S Public House","borough":"Queens","cuisine":"Irish"},
    {"id":"...","name":"Moon Light Crill Rest.","borough":"Queens","cuisine":"Indian"},
    {"id":"...","name":"Full Moon Cafe","borough":"Queens","cuisine":"Café/Coffee/Tea"},
    {"id":"...","name":"Pacific Moon","borough":"Queens","cuisine":"Chinese"},
    {"id":"...","name":"Moon Palace Kitchen","borough":"Queens","cuisine":"Chinese"},
    {"id":"...","name":"Honey Moon Coffee Shop 1766096115682","borough":"Queens","cuisine":"Café/Coffee/Tea"},
    {"id":"...","name":"Honey Moon Coffee Shop","borough":"Queens","cuisine":"Café/Coffee/Tea"}]
  3. Retrieve restaurants by cuisine type.

    The following command queries for restaurants that have a cuisine value of "Czech", but you can replace this parameter with any cuisine:

    curl http://localhost:8080/restaurants/cuisine/Czech
    [{"id":"...","name":"Koliba Restaurant","borough":"Queens","cuisine":"Czech"},
    {"id":"...","name":"Milan'S Restaurant","borough":"Brooklyn","cuisine":"Czech"},
    {"id":"...","name":"Bohemian Beer Garden","borough":"Queens","cuisine":"Czech"},
    {"id":"...","name":"Hospoda","borough":"Manhattan","cuisine":"Czech"},
    {"id":"...","name":"Olde Prague Tavern","borough":"Queens","cuisine":"Czech"},
    {"id":"...","name":"Brooklyn Beet Company","borough":"Brooklyn","cuisine":"Czech"}]

Congratulations on completing the Quarkus Quick Start tutorial! After you complete these steps, you have a Java Quarkus REST API that connects to your MongoDB deployment, runs queries on sample restaurant data, and exposes the results through HTTP endpoints that you can test by using curl commands.

To learn more about Quarkus, JNoSQL, and MongoDB, see the following resources:

Back

Spring Data MongoDB Integration

On this page