Overview
En esta guía, aprenderá a crear una API REST de Java que utiliza Quarkus como framework web y Eclipse JNoSQL para acceder a MongoDB. Quarkus es un framework Java de código abierto diseñado para microservicios nativos de la nube y desarrollo sin servidor. Eclipse JNOSQL implementa... NoSQL de Yakartay especificaciones de datos de Yakarta para simplificar la integración de aplicaciones Java con bases de datos NoSQL.
La aplicación de este tutorial consta de las siguientes capas:
Capa de base de datos: MongoDB proporciona almacenamiento y recuperación de datos.
Capa de aplicación: Quarkus maneja solicitudes HTTP, enrutamiento e inyección de dependencias.
Capa de acceso a datos: JNoSQL proporciona patrones de repositorio y mapeo de documentos de MongoDB.
¿Por qué utilizar MongoDB con Quarkus?
Este tutorial utiliza la extensión JNoSQL de Quarkus para acceder a MongoDB, que proporciona una API unificada para bases de datos NoSQL y permite trabajar con MongoDB mediante patrones y anotaciones Java habituales. Como resultado, puede usar MongoDB y Quarkus para desarrollar aplicaciones ligeras con una configuración mínima.
Al integrar MongoDB con Quarkus, puede aprovechar los rápidos tiempos de inicio y el uso eficiente de recursos de Quarkus, junto con el modelo de documentos flexible de MongoDB. Esta combinación es compatible con aplicaciones que requieren seguridad de tipos, escalabilidad y ciclos de desarrollo rápidos. Puede usar MongoDB y Quarkus para crear aplicaciones prácticas, como microservicios, API nativas de la nube o sistemas que requieren alto rendimiento y bajo consumo de recursos.
Tutorial de inicio rápido
Este tutorial muestra cómo crear una API REST que utiliza MongoDB y Quarkus. La aplicación accede a datos de muestra de restaurantes, los consulta y devuelve los resultados mediante endpoints RESTful. El tutorial también incluye instrucciones para conectarse a un clúster de MongoDB alojado en MongoDB Atlas.
Tip
Si prefiere conectarse a MongoDB utilizando el controlador Java sin Quarkus, consulte el tutorial Introducción al controlador Java.
Configurar el proyecto
Siga los pasos de esta sección para instalar las dependencias del proyecto, crear un clúster Atlas y configurar la estructura de la aplicación.
Verificar los prerrequisitos.
Para crear la aplicación de inicio rápido, instale el siguiente software en su entorno de desarrollo:
Requisito previo | notas |
|---|---|
Instale la versión JDK 21 o posterior. | |
Utilice la versión 3.8.1 o posterior. | |
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. | |
Editor de código | Utilice el editor de código de su elección. |
Aplicación de terminal y shell | Para usuarios de macOS, usen la Terminal o una aplicación similar. Para usuarios de Windows, usen PowerShell o el Símbolo del sistema. |
Crear un clúster de MongoDB Atlas.
MongoDB Atlas es un servicio de base de datos en la nube totalmente administrado que aloja sus implementaciones de MongoDB. Si no tiene una implementación de MongoDB, puede crear un clúster de MongoDB gratis completando el tutorial de introducción a MongoDB. Este tutorial también muestra cómo cargar conjuntos de datos de muestra en su clúster, incluyendo... sample_restaurants base de datos que se utiliza en este tutorial.
Para conectarse a su clúster de MongoDB, debe usar una cadena de conexión. Para saber cómo recuperarla, consulte la sección "Agregar su cadena de conexión" del tutorial "Introducción a MongoDB".
Importante
Guarde su cadena de conexión en una ubicación segura.
Crea tu proyecto Quarkus.
Desde su terminal, ejecute el siguiente comando para crear un nuevo proyecto de Quarkus llamado quarkus-quickstart que configure la extensión Quarkus JNoSQL para MongoDB y la serialización JSON para puntos finales REST:
quarkus create app quarkus-quickstart --extensions=jnosql-mongodb,resteasy-jackson
Luego, navegue al directorio de su proyecto ejecutando el siguiente comando:
cd quarkus-quickstart
Configure su conexión a la base de datos.
Navegue hasta el archivo src/main/resources/application.properties y agregue las siguientes propiedades de configuración:
jnosql.document.database=sample_restaurants quarkus.mongodb.connection-string=<connection string>
Este código configura su conexión a la sample_restaurants base de datos en su clúster de MongoDB. Reemplace el <connection string> marcador con la cadena de conexión que guardó en un paso anterior.
Limpiar archivos de plantilla.
La plantilla de proyecto de Quarkus incluye algunos archivos de ejemplo que puede eliminar para este tutorial. Para eliminar estos archivos innecesarios, seleccione la pestaña correspondiente a su sistema operativo y ejecute los siguientes comandos desde el directorio quarkus-quickstart:
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
Crea tu aplicación
Después de configurar la estructura y las dependencias del proyecto, siga los pasos de esta sección para crear su modelo de datos, clase de repositorio y puntos finales REST.
Crea el Restaurant modelo.
Cree un archivo llamado Restaurant.java en el directorio src/main/java/org/acme y pegue el siguiente código:
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. */ public class Restaurant { private String id; private String name; private String borough; 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; } }
Este archivo define la clase de entidad Restaurant, que se asigna a los documentos de la colección sample_restaurants.restaurants. La anotación @Entity marca esta clase como una entidad JNoSQL, y las anotaciones de campo asignan propiedades Java a los campos del documento.
Crea la clase de repositorio.
Cree un archivo llamado RestaurantRepository.java en el directorio src/main/java/org/acme y pegue el siguiente código:
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. * */ public interface RestaurantRepository extends NoSQLRepository<Restaurant, String> { List<Restaurant> findByBorough(String borough); List<Restaurant> findByCuisine(String cuisine); }
Esta clase de repositorio proporciona métodos para acceder a los datos de restaurantes en MongoDB. Define métodos de consulta personalizados findByBorough() y findByCuisine(), y también permite usar una instancia RestaurantRepository para acceder a los métodos integrados de creación, lectura, actualización y eliminación.
Crea la clase de recurso REST.
En el directorio src/main/java/org/acme, crea un archivo llamado RestaurantResource.java y pega el siguiente código:
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. */ public class RestaurantResource { RestaurantRepository restaurantRepository; /** * Retrieves all restaurants from the database. * * @return List of all restaurants */ 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 */ 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 */ public Response getRestaurantsByCuisine( 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(); } } }
Esta clase de recurso REST define los siguientes puntos finales HTTP:
GET /restaurants/:Recupera todos los documentos de la colecciónrestaurantsGET /restaurants/browse:Recupera documentos que representan restaurantes en Queens que contienen"Moon"en su nombre, realizando una consulta que no distingue entre mayúsculas y minúsculas.GET /restaurants/cuisine/{cuisine}:Recupera documentos que representan restaurantes que ofrecen el valorcuisineespecificado
Crear una clase de prueba.
En el directorio src/test/java/org/acme, crea un archivo llamado RestaurantRepositoryTest.java y pega el siguiente código:
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. */ public class RestaurantRepositoryTest { RestaurantRepository restaurantRepository; public void testRetrieveRestaurants() { // Test repository injection and MongoDB connection assertThat(restaurantRepository).isNotNull(); } public void testFindRestaurantsByBorough() { // Test that the method exists and returns data List<Restaurant> restaurants = restaurantRepository.findByBorough("Queens"); assertThat(restaurants).isNotNull(); } }
Este archivo utiliza el marco de pruebas de Quarkus para las pruebas de integración. El código define los siguientes métodos para probar la conexión a MongoDB:
testRetrieveRestaurants(): Verifica que su claseRestaurantRepositoryacceda a MongoDBtestFindRestaurantsByBorough(): Verifica que el métodofindByBorough()recupere datos de MongoDB
Ejecute su aplicación
Por último, siga los pasos de esta sección para ejecutar su API REST y probar los puntos finales mediante los comandos curl.
Ejecute las pruebas.
Primero, ejecute el siguiente comando desde el directorio de su proyecto para ejecutar el conjunto de pruebas:
./mvnw test
Este comando ejecuta la clase RestaurantRepositoryTest y verifica que su aplicación pueda acceder a los datos de MongoDB. Si se ejecuta correctamente, la salida del comando contendrá la siguiente información:
[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] ------------------------------------------------------------------------
Pruebe manualmente los puntos finales REST.
En una ventana de terminal independiente, ejecute los siguientes comandos curl para probar los puntos de conexión REST. Cada punto de conexión devuelve datos JSON con información del restaurante de la colección sample_restaurants.restaurants. Si la ejecución es correcta, los comandos devuelven datos similares a los de ejemplo.
Recuperar todos los restaurantes.
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"}, ...] Recupera restaurantes en Queens que tengan
"Moon"en el nombre.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"}] Recuperar restaurantes por tipo de cocina.
El siguiente comando busca restaurantes que tengan un valor
cuisinede"Czech", pero puede reemplazar este parámetro con cualquier cocina: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"}]
¡Felicitaciones por completar el tutorial de inicio rápido de Quarkus! Después de completar estos pasos, tendrá una API REST de Java para Quarkus que se conecta a su implementación de MongoDB, ejecuta consultas sobre datos de restaurantes de muestra y expone los resultados mediante puntos finales HTTP que puede probar con los comandos curl.
Recursos adicionales
Para obtener más información sobre Quarkus, JNoSQL y MongoDB, consulte los siguientes recursos:
Documentación deQuarkus
Documentación deEclipse JNoSQL
Documentación delcontrolador Java de MongoDB