Creating a tutorial

Prerequisites

  • Roughly 15 minutes

  • 一个编辑器或 IDE,使用插件或本机方式提供 AsciiDoc 的语法高亮和预览。

  • 你必须熟悉“Tutorial”の概要。

  • 准备就绪的“Quarkus style and content guidelines”作为语法需求和其他惯例的参考。

Decide on a title and file name

  1. 为教程确定一个标题。对于这个工作示例,我们将使用“Serve Http requests using the Acme extension”。

  2. 确定一个文件名。对于这个示例,我们将使用“acme-serve-http-requests-tutorial.adoc”:

    • acme-”将此指南与 acme 扩展的其他资源归为一组

    • serve-http-requests”是文档标题的派生词

    • -tutorial”将表示此文档为教程(可选)

    • .adoc”表示这是一个 AsciiDoc 文件

Copy the tutorial template

从 Quarkus 存储库复制“docs/src/main/diataxis/_templates/template-tutorial.adoc”到名为“acme-serve-http-requests-tutorial.adoc”的新文件中。

Update the document header

[id="acme-serve-http-requests-tutorial"] (1)
= Serve Http requests using the Acme extension (2)
link:_attributes.adoc[role=include]
:iokays-category: quarkus
:iokays-path: modules/ROOT/pages/doc-create-tutorial.adoc (3)
:categories: web (4)
:extension-status: experimental (5)
1 将文件名用作该部分的唯一 ID。
2 将标题添加为顶级标题。
3 包括其他属性以协助定义一致的格式并提供源代码可移植性。
4 指定 “web”类别,因为我们的假想扩展名可与 Http 请求配合使用。
5 我们的假想 “acme”扩展名是试验性的,因此我们在标题中包括了扩展名状态声明。
Document Preview

文件的预览应包含所选标题作为一页顶部的一个样式标题。

Add an abstract

我们希望让我们的教程的读者知道,在按照教程中的步骤操作之后,他们将取得怎样的成果。摘要应简洁,并应使用适当的动词(创建、构建、部署……)来设定预期。读者应能够确定他们是否希望参与内容。

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.
Document Preview

文件的预览应包含摘要,作为紧跟标题后的一个段落。

Include extension status descriptive text

acme`扩展是试验性的,我们会包含提供扩展状态文本的 `./_includes/extension-status.adoc。它使用标题中定义的扩展状态属性。

:iokays-category: quarkus
:iokays-path: modules/ROOT/pages/_includes/extension-status.adoc
:keywords: Quarkus, 中文文档, 编程技术


[NOTE]
======
该技术被认为是 {extension-status}。
有关可能状态的完整列表,请查看我们的 link:https://quarkus.io/faq/#what-are-the-extension-statuses[FAQ entry].
======
Document Preview

现在,文档的预览应包括摘要下方的警告框,说明该插件是实验性技术,并描述了对实验性技术的稳定性和支持方面的预期。

Define Prerequisites

我们需要告诉用户完成本教程所需的资源。

任何描述开发活动的教程都应使用 ./_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 包含提供描述先决条件的文本的通用文件。
Document Preview

第二层 Prerequistes 标题应紧跟在文档预览中的扩展状态框之后。它应该说明:

  • 本教程大约需要 30 分钟

  • 您需要一个 IDE、JDK(带版本)、maven(占位符为 maven 版本)、一个正在工作的容器运行时和(可选)Quarkus CLI。

Describe the steps for completing the tutorial

此过程有几部分。只需记住,每一步都应以一个可理解/可观察的结果结束:“输出应类似于这样……”

Define the first step

在指定第一步的头之前启用节号。

: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 Enable section numbering
2 为第一步创建一个第二层标题
3 Describe the step briefly
4 定义装配件 ID(Maven 或 Gradle)
5 列出此项目所需的扩展
6 使用通用文本描述如何创建项目
Document Preview

文档预览现在应包含一个名为 1. Create a new project 的新部分,其中包含使用 Quarkus CLI 和 maven 创建新项目的步骤。

Using a source file

在本教程中,我们将使用标签包含来自单独 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::) 定义。

Provide concise subsequent steps

现在让我们指导学习者使用虚构的 @Anvil 注解创建一个简单的端点。

Create a source code file

我们将从在文件中创建并添加端点的步骤开始。

== 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]

Unresolved include directive in modules/ROOT/pages/doc-create-tutorial.adoc - include::./_examples/acme-serve-http-requests-MyAcmeApplication.java[]

<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, conceptreference)。

Document Preview

预览应包含一个新章节 2. Hello, World! as an Acme REST service,其中包含 src/main/java/org/acme/MyAcmeApplication.java 的内容,省略了 goodbye 方法。

Explore continuous development and test

现在是指导用户启动 Quarkus dev 模式的时候了。常见包括项对我们来说做了大部分工作:

== Dev Mode: Hello, World!

Let's run our application using Quarkus' iterative development mode:

:iokays-category: quarkus
:iokays-path: modules/ROOT/pages/_includes/devtools/dev.adoc
:keywords: Quarkus, 中文文档, 编程技术

[source, bash]
.CLI

quarkus dev

[source, bash]
.Maven
/mvnw quarkus:dev
[source, bash]
.Gradle
/gradlew --console=plain quarkusDev
Once the console output from dev mode indicates that things are ready, use `curl` to invoke the `hello` endpoint:

[source,shell]

$ curl -w "\n" http://localhost: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.

我们在此提供了一些信息:

  • 我们使用描述如何启动 dev 模式的常用文本。

  • 我们描述如何使用 curl 来测试我们定义的端点的输出。

Document Preview

预览应包括一个新章节,“3. Dev 模式:Hello, World!”该部分应包括使用 Quarkus dev 模式的三个方法(cli、maven 和 gradle)。它应包含包含 curl 控制台命令和输出的代码块以及退出 dev 模式的说明。

Adding tests

现在,让我们引导用户向其应用程序中添加测试:

== 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]

Unresolved include directive in modules/ROOT/pages/doc-create-tutorial.adoc - include::./_examples/acme-serve-http-requests-MyAcmeApplicationTest.java[]

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 区域标记来从列表中排除一个方法(我们稍后会添加该方法)。

Document Preview

预览应包含一个新的部分 4. Testing: Hello, World!,其中包含 `src/main/java/org/acme/MyAcmeApplicationTest.java`的内容,但省略了 `testGoodbyeEndpoint`方法。

Add additional capabilities

让我们添加另一个步骤,以使用虚拟 `@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]

Unresolved include directive in modules/ROOT/pages/doc-create-tutorial.adoc - include::./_examples/acme-serve-http-requests-MyAcmeApplication.java[]

<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]

Unresolved include directive in modules/ROOT/pages/doc-create-tutorial.adoc - include::./_examples/acme-serve-http-requests-MyAcmeApplicationTest.java[]

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`一词,从而帮助用户找到与其他相关材料(如何、概念或参考)的路径。

Document preview

预览现在应包含两个新部分,5. Goodbye, Sweet Planet! Server sent events with Acme`和 `6. Testing: Goodbye, Sweet Planet!。 两个新的代码列表应重点关注之前遗漏的方法:goodbye`来自 `src/main/java/org/acme/MyAcmeApplication.java,以及 testGoodbyeEndpoint`来自 `src/main/java/org/acme/MyAcmeApplicationTest.java

Provide a Summary section

: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 Turn off section numbering
2 祝贺用户出色完成任务!
Document preview

预览现在应包含一个未编号的 `Summary`部分。

Summary

恭喜!您已创建了一个教程,其中描述了如何创建使用不可理解的注释的应用程序,这些注释来自一个虚拟扩展。

将结果与完整的操作示例进行比较:

link:{doc-examples}/acme-serve-http-requests-tutorial.adoctxt[role=include]