创建教程
创建新的教程,指导用户完成创建、运行和测试一个使用来自假想扩展的注解的 Quarkus 应用程序。
先决条件
-
大约 15 分钟
-
一个能够原生或通过插件提供 AsciiDoc 语法高亮和预览的编辑器或 IDE。
-
您应该熟悉 教程 的概述。
-
随身携带 Quarkus 风格和内容指南 作为所需语法和其他约定的参考。
1. 决定标题和文件名
-
为教程决定一个标题。对于这个实际示例,我们将使用
使用 Acme 扩展处理 HTTP 请求
。 -
决定一个文件名。对于这个示例,我们将使用
acme-serve-http-requests-tutorial.adoc
-
acme-
将把本指南与其他与 acme 扩展相关的资源分组 -
serve-http-requests
是文档标题的派生 -
-tutorial
将表明这是一个教程(可选) -
.adoc
表明这是一个 asciidoc 文件
-
2. 复制教程模板
将 Quarkus 仓库中的 docs/src/main/diataxis/_templates/template-tutorial.adoc
复制到一个名为 acme-serve-http-requests-tutorial.adoc
的新文件中。
3. 更新文档头
[id="acme-serve-http-requests-tutorial"] (1)
= Serve Http requests using the Acme extension (2)
include::_attributes.adoc[] (3)
:categories: web (4)
:extension-status: experimental (5)
1 | 使用文件名作为该部分的唯一 ID。 |
2 | 将标题添加为顶级标题。 |
3 | 包含其他属性,以帮助定义一致的格式并提供源可移植性。 |
4 | 指定 web 类别,因为我们假想的扩展程序处理 HTTP 请求。 |
5 | 我们假想的 acme 扩展是实验性的,因此我们在头部包含扩展状态声明。 |
您的文档预览应在页面顶部包含所选标题作为样式化的标题。
4. 添加摘要
我们希望让教程的读者知道他们将通过遵循教程中的步骤来实现什么。这个摘要应该简洁,并使用适当的动词(创建、构建、部署……)来设定期望。他们应该能够判断是否要参与内容。
Create an application that uses unique annotations from the experimental acme extension to define two endpoints:
a simple HTTP endpoint and an endpoint that emits server-sent events (SSE).
We will also use Quarkus dev mode for iterative development and testing.
您的文档预览应在标题之后立即包含摘要作为段落。
5. 包含扩展状态描述性文本
由于 acme
扩展是实验性的,我们将包含 {includes}/extension-status.adoc
,它提供了扩展状态文本。它使用了头部定义的扩展状态属性。
include::{includes}/extension-status.adoc[]
您的文档预览现在应该在摘要下方包含一个警告框,解释该插件是实验性技术,并描述了在稳定性或实验性技术支持方面可以预期的内容。
6. 定义先决条件
我们需要告诉用户完成教程所需的资源。
任何描述开发活动的教程都应该使用 {includes}/prerequisites.adoc
,以确保在描述先决条件时使用一致的语言。声明的 prerequisites-
属性可以自定义最终文本。
== Prerequisites
:prerequisites-time: 30 minutes (1)
:prerequisites-docker: (2)
:prerequisites-no-graalvm: (3)
include::{includes}/prerequisites.adoc[] (4)
The `curl` command line utility is also used to manually test the endpoint.
1 | 声明我们的假设教程大约需要 30 分钟完成。 |
2 | 声明我们无意义的 acme 扩展还需要一个容器运行时。 |
3 | 为了在本教程中简化,我们将避免 GraalVM 和 Mandrel 的先决条件。 |
4 | 包含提供先决条件文本的常用文件。 |
一个二级的 先决条件
标题应紧随您文档预览中的扩展状态框。它应该说明
-
本教程大约需要 30 分钟
-
您需要一个 IDE、JDK(带版本)、Maven(带 Maven 版本的占位符)、一个工作的容器运行时,以及(可选)Quarkus CLI。
7. 描述完成教程的步骤
这个过程有几个部分。请记住,每个步骤都应该以一个可理解/可观察的结果结束:“输出应该看起来像这样……”
7.1. 定义第一步
在指定第一步的标题之前启用节编号。
:sectnums: (1)
:sectnumlevels: 3
== Create a new project (2)
Create a new project with the following command: (3)
:create-app-artifact-id: acme-quickstart (4)
:create-app-extensions: acme (5)
include::{includes}/devtools/create-app.adoc[] (6)
1 | 启用节编号 |
2 | 为第一步创建一个二级标题 |
3 | 简要描述这一步 |
4 | 定义 artifact ID(Maven 或 Gradle) |
5 | 列出此项目所需的扩展 |
6 | 使用常用文本描述如何创建项目 |
文档预览现在应该包含一个名为 1. 创建新项目
的新部分,其中包含使用 Quarkus CLI 和 Maven 创建新项目的步骤。
7.2. 使用源文件
在本教程中,我们将使用标签包含一个单独的 Java 文件中的代码。
这可以视为一个有抱负的示例。通常将源文件直接包含在源代码块中。虽然从 Java 文件包含源有其优点,但我们在引用代码应该放在哪里方面还有一些细节需要解决。欢迎帮助和想法! |
让我们创建一个名为 acme-serve-http-requests-MyAcmeApplication.java
的文件。虽然这不是一个有效的 Java 文件名,但它与我们的教程源文件放在一起很方便。我们将依赖 IDE 的魔力来进行语法检查。
让我们将以下代码添加到该文件中
// tag::application[]
package org.acme;
import jakarta.enterprise.context.ApplicationScoped;
import org.acme.corp.Anvil;
import org.acme.corp.Toaster;
import io.smallrye.mutiny.Multi;
@ApplicationScoped // <1>
public class MyAcmeApplication {
@Anvil(optional = {"name"}) // <2>
public String hello(String name) {
return String.format("Hello, %s!", (name == null ? "World" : name));
}
// tag::goodbye[]
@Toaster // <1>
public Multi<String> longGoodbye(String name) {
return Multi.createFrom().items("Goodbye", ",", "Sweet", "Planet", "!"); // <2>
}
// end::goodbye[]
}
// end::application[]
这段代码示例有几点值得注意
-
AsciiDoc 的调用示例显示在某些行的注释中,并且它们的编号不是连续的。
-
AsciiDoc 内容区域由注释中的标签对(
tag::
和end::
)定义,这些标签对环绕着代码的不同部分。
7.3. 提供简洁的后续步骤
现在,让我们指导学习者使用假想的 @Anvil
注解创建一个简单的端点。
7.3.1. 创建源文件
我们将从创建端点并将其添加到文件所需的步骤开始。
== Hello, World! as an Acme REST service
Let's create a Http endpoint using the `@Anvil` annotation.
Create a new source file, `src/main/java/org/acme/MyAcmeApplication.java`, and define the `MyAcmeApplication` bean as follows:
[source,java]
----
include::{doc-examples}/acme-serve-http-requests-MyAcmeApplication.java[tags=*;!goodbye]
----
<1> Specify the CDI lifecycle of this bean.
An `@ApplicationScoped` bean has a single bean instance that is used for the application.
<2> The `@Anvil` annotation always implies a simple Http GET request with the uri derived from the method name, `/hello` in this case.
The `optional` value indicates that the `name` parameter is not required.
这些说明的一些注意事项
-
我们使用 Asciidoc 标记区域包含源文件中的代码,同时使用标记区域将
goodbye
方法排除在列表之外。 -
我们提供了一些关于
@ApplicationScoped
含义的上下文,但没有深入探讨替代的 CDI 生命周期。 -
我们描述了
@Anvil
在本教程涵盖的特定情况下提供了什么。
在教程中要小心解释的量。在教程中包含足够的信息,以帮助用户确定他们应该查看哪些其他资源(howto 、concept 或 reference )。 |
您的预览应包含一个名为 2. Hello, World! 作为 Acme REST 服务
的新部分,其中包含 src/main/java/org/acme/MyAcmeApplication.java
的内容,并省略了 goodbye
方法。
7.3.2. 探索持续开发和测试
现在是时候引导用户启动 Quarkus 开发模式了。一个通用的包含文件为我们完成了大部分工作
== Dev Mode: Hello, World!
Let's run our application using Quarkus' iterative development mode:
include::{includes}/devtools/dev.adoc[]
Once the console output from dev mode indicates that things are ready, use `curl` to invoke the `hello` endpoint:
[source,shell]
----
$ curl -w "\n" https://:8080/hello
Hello, World!
----
Pass the name as a parameter:
[source,bash,subs=attributes+]
----
$ curl localhost:8080/hello -d '{"name": "bananas"}'
Hello, bananas!
----
You can leave dev mode running throughout the rest of the tutorial for continuous feedback as you make changes to code.
Use `CTRL-C` to exit dev mode.
我们在这里提供了一些内容
-
我们正在使用通用文本描述如何启动开发模式。
-
我们描述了如何使用
curl
测试我们定义的端点的输出。
您的预览应包含一个名为“3. 开发模式:Hello, World!”的新部分。该部分应包含启动 Quarkus 开发模式的三种方法(cli、maven、gradle)。它应该包含包含 curl 控制台命令和输出的代码块,以及退出开发模式的说明。
7.3.3. 添加测试
现在让我们引导用户为他们的应用程序添加一个测试
== Testing: Hello, World!
Let's create a test to work with our `@Anvil` endpoint.
Create a new source file, `src/test/java/org/acme/MyAcmeApplicationTest.java`, and define `MyAcmeApplicationTest` as follows:
[source,java]
----
include::{doc-examples}/acme-serve-http-requests-MyAcmeApplicationTest.java[tags=*;!goodbye]
----
After saving, the dev console should detect the presence of tests, but it isn't running by default.
The bottom of the console screen will display a message indicating that running tests have been paused.
Press `r` to resume testing.
You should see the status change as tests are running, and it should finish with a message indicating that 1 test was run and that it was successful.
我们正在使用 Asciidoc 区域标签排除目标文件中的一个方法(我们稍后会添加)。
您的预览应包含一个名为 4. 测试:Hello, World!
的新部分,其中包含 src/main/java/org/acme/MyAcmeApplicationTest.java
的内容,并省略了 testGoodbyeEndpoint
方法。
7.3.4. 添加其他功能
让我们添加另一个步骤,使用假想的 @Toaster
注解创建一个不同的端点,并提供相应的测试。
== Goodbye, Sweet Planet! Server sent events with Acme
Let's add an endpoint that supports Server Sent Events using the `@Toaster` annotation:
[source,java]
----
include::{doc-examples}/acme-serve-http-requests-MyAcmeApplication.java[tag=goodbye]
----
<1> The `@Toaster` annotation indicates that this method emits Server-Sent Events.
<2> A `Multi` is an asynchronous publisher of multiple events provided by Mutiny, the event-driven reactive streams library used by Quarkus.
== Testing: Goodbye, Sweet Planet!
Let's create a test to work with our `@Toaster` endpoint.
Add the following method to `src/test/java/org/acme/MyAcmeApplicationTest.java`:
[source,java]
----
include::{doc-examples}/acme-serve-http-requests-MyAcmeApplicationTest.java[tag=goodbye]
----
After saving, the dev console should detect the presence of the additional test, and run both.
You should see a message that 2 tests were run, and both were successful.
几点说明
-
我们正在使用 AsciiDoc 区域标签仅包含目标文件的一个区域。
-
我们不详细解释概念
-
我们讨论了
@Toaster
注解在此示例中的作用。 -
我们定义了
Multi
一词,以帮助用户找到其他相关材料(How to、Concept 或 Reference)。
-
您的预览现在应包含两个新部分,5. Goodbye, Sweet Planet! 使用 Acme 进行服务器发送事件
和 6. 测试:Goodbye, Sweet Planet!
。
两个新的代码列表应集中在之前省略的方法上:src/main/java/org/acme/MyAcmeApplication.java
中的 goodbye
方法,以及 src/main/java/org/acme/MyAcmeApplicationTest.java
中的 testGoodbyeEndpoint
方法。
8. 提供摘要部分
:sectnums!: (1)
== Summary
Congratulations! You have created a project that uses the acme extension to create fanciful endpoints using the `@Anvil` and `@Toaster` annotations. (2)
1 | 关闭节编号 |
2 | 祝贺用户圆满完成任务! |
您的预览现在应该包含一个未编号的 摘要
部分。
总结
恭喜!您已经创建了一个教程,该教程描述了如何创建一个使用假设扩展中具有可疑价值的注解的应用程序。
将您的结果与完整的实际示例进行比较
////
This document is maintained in the main Quarkus repository
and pull requests should be submitted there:
https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc
////
[id="acme-serve-http-requests-tutorial"]
= Serve Http requests using the Acme extension
include::_attributes.adoc[]
:diataxis-type: tutorial
:categories: web
:extension-status: experimental
Create an application that uses unique annotations from the experimental acme extension to define two endpoints:
a simple HTTP endpoint and an endpoint that emits server-sent events (SSE).
We will also use Quarkus dev mode for iterative development and testing.
include::{includes}/extension-status.adoc[]
== Prerequisites
:prerequisites-time: 30 minutes
:prerequisites-docker:
:prerequisites-no-graalvm:
include::{includes}/prerequisites.adoc[]
The `curl` command line utility is also used to manually test the endpoint.
:sectnums:
:sectnumlevels: 3
== Create a new project
Create a new project with the following command:
:create-app-artifact-id: acme-quickstart
:create-app-extensions: acme
include::{includes}/devtools/create-app.adoc[]
== Hello, World! as an Acme Http service
Let's create a Http endpoint using the `@Anvil` annotation.
Create a new source file, `src/main/java/org/acme/MyAcmeApplication.java`,
and define the `MyAcmeApplication` bean as follows:
[source,java]
----
include::{examples}/acme-serve-http-requests-MyAcmeApplication.java[tags=*;!goodbye]
----
<1> Specify the CDI lifecycle of this bean.
An `@ApplicationScoped` bean has a single bean instance that is used for the application.
<2> The `@Anvil` annotation always implies a simple Http GET request with the uri derived from the method name, `/hello` in this case.
The `optional` value indicates that the `name` parameter is not required.
== Dev Mode: Hello, World!
Let's run our application using Quarkus' iterative development mode:
include::{includes}/devtools/dev.adoc[]
Once the console output from dev mode indicates that things are ready, use `curl` to invoke the `hello` endpoint:
[source,shell]
----
$ curl -w "\n" https://:8080/hello
Hello, World!
----
Pass the name as a parameter:
[source,bash,subs=attributes+]
----
$ curl localhost:8080/hello -d '{"name": "bananas"}'
Hello, bananas!
----
You can leave dev mode running throughout the rest of the tutorial for continuous feedback as you make changes to code.
Use `CTRL-C` to exit dev mode.
== Testing: Hello, World!
Let's create a test to work with our `@Anvil` endpoint.
Create a new source file, `src/test/java/org/acme/MyAcmeApplicationTest.java`, and define `MyAcmeApplicationTest` as follows:
[source,java]
----
include::{examples}/acme-serve-http-requests-MyAcmeApplicationTest.java[tags=*;!goodbye]
----
After saving, the dev console should detect the presence of tests, but it isn't running by default.
The bottom of the console screen will display a message indicating that running tests have been paused.
Press `r` to resume testing.
You should see the status change as they are running, and it should finish with a message indicating that 1 test was run and that it was successful.
== Goodbye, Sweet Planet! Server sent events with Acme
Let's add an endpoint that supports Server Sent Events using the `@Toaster` annotation:
[source,java]
----
include::{examples}/acme-serve-http-requests-MyAcmeApplication.java[tag=goodbye]
----
<1> The `@Toaster` annotation indicates that this method emits Server-Sent Events.
<2> A `Multi` is an asynchronous publisher of multiple events provided by Mutiny, the event-driven reactive streams library used by Quarkus.
== Testing: Goodbye, Sweet Planet!
Let's create a test to work with our `@Toaster` endpoint.
Add the following method to `src/test/java/org/acme/MyAcmeApplicationTest.java`:
[source,java]
----
include::{examples}/acme-serve-http-requests-MyAcmeApplicationTest.java[tag=goodbye]
----
After saving, the dev console should detect the presence of the additional test, and run both.
You should see a message that 2 tests were run, and both were successful.
:sectnums!:
== Summary
Congratulations!
You have created a project that uses the acme extension to create fanciful endpoints using the `@Anvil` and `@Toaster` annotations.