Overview
在本指南中,您可以学习;了解如何创建Java REST API ,该 API 使用 Quarkus 作为 Web框架和 Eclipse JNoSQL 来访问权限MongoDB。 Quarkus 是一个开源Java框架,专为云原生微服务和无服务器开发而设计。 Eclipse JNOSQL 实施 Jakarta NoSQL 和 Jakarta Data 规范,以简化Java应用程序与 NoSQL 数据库的集成。
本教程中的应用程序由以下各层组成:
数据库层:MongoDB提供数据存储和检索。
应用程序层:Quarkus 处理HTTP请求、路由和依赖项注入。
数据访问权限层:JNoSQL 提供MongoDB文档映射和存储库模式。
为何将MongoDB与 Quarkus 结合使用?
本教程使用 Quarkus JNoSQL 扩展访问权限MongoDB,该扩展为 NoSQL 数据库提供了统一的API ,并允许您通过熟悉的Java模式和注解来使用MongoDB 。因此,您可以使用MongoDB和 Quarkus 以最少的配置开发轻量级应用程序。
通过将MongoDB与 Quarkus 集成,您可以利用 Quarkus 的快速初创企业时间和高效的资源利用以及 MongoDB 灵活的文档模型。这种组合支持需要类型安全、可扩展性和快速开发周期的应用程序。您可以使用MongoDB和 Quarkus 来创建实际应用程序,例如微服务、云原生 API 或需要高性能和低资源消耗的系统。
快速入门教程
本教程向您展示如何构建使用MongoDB和 Quarkus 的REST API 。该应用程序访问示例餐厅数据,查询数据,并通过 RESTful 端点返回结果。本教程还包括连接到MongoDB Atlas上托管的MongoDB 集群的说明。
设置您的项目
按照本节中的步骤安装项目依赖项,创建Atlas集群,并设立应用程序结构。
验证先决条件。
要创建快速入门应用程序,请在开发环境中安装以下软件:
先决条件 | 注意 |
|---|---|
安装 JDK 版本 21 或更高版本。 | |
使用 3.8.1 或更高版本。 | |
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. | |
代码编辑器 | 使用您选择的代码编辑器。 |
终端应用和shell | 对于 MacOS 用户,请使用终端或类似应用。对于Windows用户,请使用 PowerShell 或命令提示符。 |
配置数据库连接。
导航到 src/main/resources/application.properties文件并添加以下配置属性:
jnosql.document.database=sample_restaurants quarkus.mongodb.connection-string=<connection string>
sample_restaurants此代码将配置与MongoDB 集群中 数据库的连接。将<connection string> 占位符替换为在上一步中保存的连接字符串。
清理模板文件。
Quarkus项目模板包含一些示例文件,您可以在本教程中删除这些文件。要删除这些不需要的文件,请选择与操作系统对应的标签页,然后从 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
创建应用程序
设置项目结构和依赖项后,请按照本节中的步骤创建数据模型、存储库类和 REST 端点。
创建Restaurant 模型。
在 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. */ 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; } }
此文件定义了 Restaurant 实体类,它映射到 sample_restaurants.restaurants集合中的文档。 @Entity 注释将此类标记为 JNoSQL 实体,字段注释将Java属性映射到文档字段。
创建存储库库类。
在 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. * */ public interface RestaurantRepository extends NoSQLRepository<Restaurant, String> { List<Restaurant> findByBorough(String borough); List<Restaurant> findByCuisine(String cuisine); }
该存储库库类提供了访问MongoDB中餐厅数据的方法。它定义了自定义 findByBorough() 和 findByCuisine()查询方法,您还可以使用 RestaurantRepository实例访问权限内置的创建、读取、更新和删除方法。
创建 REST资源类。
在 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. */ 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(); } } }
此 REST资源类定义以下HTTP端点:
GET /restaurants/:检索restaurants集合中的所有文档GET /restaurants/browse:检索代表皇后区名称中包含"Moon"的餐厅的文档,执行不区分大小写的查询GET /restaurants/cuisine/{cuisine}:检索代表提供指定cuisine值的餐厅的文档
创建一个测试类。
在 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. */ 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(); } }
该文件使用 Quarkus 的测试框架进行集成测试。该代码定义了以下方法来测试MongoDB连接:
testRetrieveRestaurants():验证您的RestaurantRepository类是否可以访问MongoDBtestFindRestaurantsByBorough():验证findByBorough()方法是否检索MongoDB数据
运行应用程序
最后,按照本部分中的步骤运行REST API并使用 curl 命令测试端点。
运行测试。
首先,从项目目录运行以下命令来运行测试套件:
./mvnw test
此命令运行 RestaurantRepositoryTest 类并验证您的应用程序是否可以访问权限MongoDB数据。如果成功,命令输出将包含以下信息:
[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] ------------------------------------------------------------------------
手动测试 REST 端点。
在单独的终端窗口中,运行以下 curl 命令以测试 REST 端点。每个端点返回包含 sample_restaurants.restaurants集合中的餐厅信息的JSON数据。如果成功,您的命令将返回与示例输出类似的数据。
检索所有餐厅。
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"}, ...] 检索名称中包含
"Moon"的皇后区餐厅。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"}] 按菜系类型检索餐厅。
以下命令会查询
cuisine值为"Czech"的餐厅,但您可以将此参数替换为任何菜系: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"}]
恭喜您完成 Quarkus 快速入门教程!完成这些步骤后,您就拥有一个Java Quarkus REST API ,它可以连接到MongoDB 部署、对示例餐厅数据运行查询,并通过HTTP端点公开结果,您可以使用 curl 命令测试这些结果。
其他资源
要学习;了解有关 Quarkus、JNoSQL 和MongoDB 的更多信息,请参阅以下资源: