在本文中,我们将开始使用第一个超音速Quarkus应用程序。 我们将使用熟悉的JAX-RS和CDI API开发RESTful应用程序,学习如何在Quarkus环境中运行它,以及如何测试它。
Recently, Quarkus 1.0 has been announced, an important milestone for the Java community.
Quarkus is an Open Source stack to write Java applications offering unparalleled startup time, memory footprint and developer experience. It offers familiar programming models and APIs (Hibernate, JAX-RS, Eclipse Vert.x, Apache Camel, Eclipse MicroProfile, Spring API compatibility and more).
In this article, we're going to getting started with our first Quarkus application, more specifically a RESTful application using the familiar JAX-RS and CDI APIs from Jakarta EE. We will also see how to test our application. You can find the source code on my GitHub.
1. Prerequisites
要遵循本教程,您将需要:
- JDK 8或11+一个IDEApache Maven 3.5.3+摇篮5.5.0+
我将使用Gradle来构建应用程序,但是您可以自由使用Maven。 请注意,将Quardle与Gradle一起使用是预览功能。 它可能不支持所有可能的方案,但是对于我们将在本教程中构建的应用程序来说,它已经足够好了。
2. Bootstrapping a Quarkus Application
我们将要开发的应用程序是一个针对库的虚拟RESTful应用程序,它公开了一个端点来获取所有可用的书。
我们可以通过两种方式快速引导Quarkus应用程序:从命令行利用Maven或使用方便的基于UI的应用程序生成器。
在这两种情况下,我们都需要提供一些重要信息:
- 组和工件ID构建工具(Maven或Gradle)扩展名(即依赖项)。
的RESTeasy JAX-RS默认情况下包含扩展名,而我们需要包含RESTeasy JSON-B扩展名。
使用Maven生成器,我们还可以指定要为JAX-RS自动生成和配置的资源类以及可选路径。
让我们看看这两个选项。
Using Maven to generate a Quarkus application
让我们打开一个终端窗口并运行以下命令来生成一个应用程序,它将使用Maven作为内置工具:
mvn io.quarkus:quarkus-maven-plugin:1.0.0.CR1:create \
-DprojectGroupId=com.thomasvitale \
-DprojectArtifactId=quarkus-getting-started \
-DclassName="com.thomasvitale.library.BookResource" \
-Dpath="/books" \
-Dextensions="resteasy-jsonb"
如果我们希望使用Gradle作为构建应用程序的工具,则可以通过这种方式进行操作(注意buildTool参数):
mvn io.quarkus:quarkus-maven-plugin:1.0.0.CR1:create \
-DprojectGroupId=com.thomasvitale \
-DprojectArtifactId=quarkus-getting-started \
-DclassName="com.thomasvitale.library.BookResource" \
-Dpath="/books" \
-Dextensions="resteasy-jsonb" \
-DbuildTool=gradle
Using the UI-based initializer to generate a Quarkus application
In alternative to Maven, we can go to code.quarkus.io and create our Quarkus application from a convenient user interface where to insert all the details about the project, the build tool and the extensions we need. Are you familiar with the Spring 一世nitializr? This tool works in the same way.
3. The Structure of a Quarkus Application
生成的Quarkus应用程序的基本结构遵循Maven标准。 最重要的是,还有一些额外的功能。
如上一节所定义,我们可以注意到BookResource类已在中生成src /主/ java,以及src /测试/ java和src /本地测试/ java。 第一个测试在JVM模式下运行,第二个测试在纯模式下运行。 的BookResource暴露于/图书 endpoint和accessible by default on http://本地主机:8080。
在src / main / docker,我们可以找到例子Docker文件文件以在JVM或纯模式下的容器中运行我们的应用程序。
为了轻松地构建应用程序,应用了Quarkus插件(适用于Maven或Gradle),并导入了Quarkus BOM,以定义我们要在整个应用程序中使用的版本。
在我们的依赖项部分gradle.build文件(或pom.xml(如果使用Maven),我们可以找到为生成器定义的RESTeasy扩展,以及JUnit5和RestAssured,以在JVM和纯模式下测试我们的应用程序。
dependencies {
implementation 'io.quarkus:quarkus-resteasy-jsonb'
implementation 'io.quarkus:quarkus-resteasy'
testImplementation 'io.quarkus:quarkus-junit5'
testImplementation 'io.rest-assured:rest-assured'
nativeTestImplementation 'io.quarkus:quarkus-junit5'
nativeTestImplementation 'io.rest-assured:rest-assured'
}
4. JVM vs Native Mode
在上一节中,我们提到了几次JVM和纯模式。 需要进行一些澄清。
JVM模式利用标准JVM。 它对运行时进行了调整,使其仅包括应用程序实际需要的内容,从而消除了标准企业运行时的所有额外动态。 与传统的企业应用程序相比,这将降低内存消耗,并加快启动阶段和首次响应时间。
The Quarkus JVM mode is already a significant advantage over the traditional enterprise Java application. In reality, what makes Quarkus shines is its native mode. Quarkus has been designed around a container first philosophy, with native support for GraalVM and SubstrateVM. When using this mode, our applications are pre-built and compiled to native executables which start up almost immediately and are incredibly well-performant both in terms of time and memory consumption.
在本教程中,我们将以JVM模式运行该应用程序及其测试。 相反,在以后的文章中,我们将看到纯模式如何工作。
5. Implementing the REST API
现在,让我们开始实际的开发阶段。 一种BookResource类已经为我们生成。 是时候实现一些端点了。
我们将公开两个端点:
- /图书返回图书馆中可用的书籍清单;/图书/{id} returns the book having the specified id.
@Path("/books")
@Produces(MediaType.APPLICATION_JSON)
public class BookResource {
@Inject
BookService bookService;
@GET
public List<Book> getBooks() {
return bookService.getBooks();
}
@GET
@Path("{id}")
public Book getBookById(@PathParam("id") Long id) {
return bookService.getBookById(id);
}
}
有趣的是,与Jakarta EE中使用的香草JAX-RS不同,在Quarkus中,我们不需要定义应用带有注释的类@应用Path启用REST API。 另外,默认情况下,资源类配置为@应用Scoped。 您可以使用CDI中熟悉的注释来更改配置,以定义类的范围。
检索书籍的功能委托给图书服务类,作为CDI bean注入BookResource。 该服务定义了一个静态地图来模拟书籍存储库。
@ApplicationScoped
public class BookService {
private static Map<Long, Book> bookRepository = new ConcurrentHashMap<>();
static {
bookRepository.put(1L, new Book(1L, "Harry Potter"));
bookRepository.put(2L, new Book(2L, "The Lord of The Rings"));
bookRepository.put(3L, new Book(3L, "The Golden Compass"));
}
List<Book> getBooks() {
return new ArrayList<>(bookRepository.values());
}
Book getBookById(Long id) {
return bookRepository.get(id);
}
}
最后,书类是一个POJO。
public class Book {
private Long id;
private String title;
Book(Long id, String title) {
this.id = id;
this.title = title;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
}
6. Running the Quarkus Application
是时候第一次运行我们的Quarkus应用程序了。 准备一些超音速亚原子部署?
让我们打开一个终端窗口并运行命令:
./gradlew assemble quarkusDev
如果使用Maven,我们可以运行以下命令:
./mvnw compile quarkus:dev
的夸库斯任务(或quarkus:dev when using Maven) runs Quarkus in development mode. 的main feature of this mode is the hot deployment with background compilation, which means we can modify our source files (both Java classes and resources) while the application is running and the changes will automatically take effect.
在开发模式下运行Quarkus时,默认情况下启用调试模式,侦听端口5005无需挂起JVM。
现在,让我们验证一下它是否有效。 在终端中,我们调用全新的REST API:
curl http://localhost:8080/books/1
结果如下:
{"id":1,"title":"Harry Potter"}
太好了,它正在运作!
7. Testing
我们手动验证了REST终结点已正确暴露给Quarkus应用程序,但是最好编写一些自动测试程序。
Let's use the BookResourceTest
class in src/test/java
that has been already generated for us and let's write a couple of tests for the two endpoints exposed by the BookResource
class. As mentioned before, we're going to use JUnit5 and RestAssured to write our tests.
@QuarkusTest
public class BookResourceTest {
@Test
void testGetBooks() {
given()
.when().get("/books")
.then()
.statusCode(200)
.body("id", hasItems(1, 2, 3));
}
@Test
void testGetBookById() {
given()
.pathParam("id", 1)
.when().get("/books/{id}")
.then()
.statusCode(200)
.body("id", is(1));
}
}
的@QuarkusTest批注确保在开始测试之前应用程序正在运行。
可以直接从我们的IDE或构建工具运行测试。 如果我们使用Gradle:
./gradlew test
使用Maven代替,我们运行以下命令:
./mvnw test
超! 现在,我们还进行了自动测试,以确保我们的应用程序能够按预期工作。
Conclusion
在本文中,我们首先了解了Quarkus。 我们探索了生成基本Quarkus项目的不同方法,并研究了其结构以识别应用程序的所有主要部分。 然后,我们利用熟悉的企业Java的JAX-RS和CDI API实现了一个简单的RESTful应用程序,并学习了如何在开发模式下运行Quarkus应用程序。 最后,我们通过编写一些自动测试并学习如何运行它们来确保正确实现了应用程序。
Quarkus肯定会留下来,我很期待看到它将如何改变企业Java应用程序的格局。 你呢? 让我知道您对Quarkus的看法,以及是否考虑在以后的项目中开始使用它。
Did you like this article? Check out my personal blog for more: thomasvitale.com. I write about Enterprise Java, Spring, Keycloak and Application Security.