Creating a tutorial
创建一项新教程,指导用户创建、运行和测试 Quarkus 应用,该应用使用来自假想扩展名的注释。
Create a new tutorial that guides users through creating, running, and testing a Quarkus application that uses annotations from an imaginary extension.
Prerequisites
-
Roughly 15 minutes
-
An editor or IDE that provides syntax highlighting and previews for AsciiDoc, either natively or using a plugin.
-
You should be familiar with the overview of what a Tutorial is.
-
Have the Quarkus style and content guidelines handy as a reference for required syntax and other conventions.
Decide on a title and file name
-
Decide on a title for the tutorial. For this worked example, we will use
Serve Http requests using the Acme extension
. -
Decide on a file name. For this example, we will use
acme-serve-http-requests-tutorial.adoc
:-
acme-
will group this guide with other resources related to the acme extension -
serve-http-requests
is a derivative of the document title -
-tutorial
will indicate that this document is a tutorial (optional) -
.adoc
to indicate this is an asciidoc file
-
Copy the tutorial template
从 Quarkus 存储库复制“docs/src/main/diataxis/_templates/template-tutorial.adoc
”到名为“acme-serve-http-requests-tutorial.adoc
”的新文件中。
Copy docs/src/main/diataxis/_templates/template-tutorial.adoc
from the Quarkus repository into a new file called 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)
:iokays-category: quarkus
:iokays-path: modules/ROOT/pages/_attributes.adoc
:keywords: Quarkus, 中文文档, 编程技术
:iokays-category: quarkus
:iokays-path: modules/ROOT/pages/_attributes-local.adoc
:iokays-category: quarkus
:iokays-path: modules/ROOT/pages/doc-create-tutorial.adoc (3)
:categories: web (4)
:extension-status: experimental (5)
1 | Use the file name as a unique id for the section. |
2 | Add the title as a top-level heading. |
3 | Include additional attributes that help define consistent formatting and provide source portability. |
4 | Specify the web category, as our imaginary extension works with Http requests. |
5 | Our imaginary acme extension is experimental, so we include the extension status declaration in the header. |
文件的预览应包含所选标题作为一页顶部的一个样式标题。
The preview of your document should contain the chosen title as a styled header at the top of the page.
Add an abstract
我们希望让我们的教程的读者知道,在按照教程中的步骤操作之后,他们将取得怎样的成果。摘要应简洁,并应使用适当的动词(创建、构建、部署……)来设定预期。读者应能够确定他们是否希望参与内容。
We want to let the readers of our tutorial know what they will achieve by following the steps in the tutorial. This abstract should be concise and should use appropriate verbs (create, build, deploy, …) to set expectations. They should be able to determine if they want to engage with the content.
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.
文件的预览应包含摘要,作为紧跟标题后的一个段落。
The preview of your document should contain the abstract as a paragraph immediately following the header.
Include extension status descriptive text
acme`扩展是试验性的,我们会包含提供扩展状态文本的 `{includes}/extension-status.adoc
。它使用标题中定义的扩展状态属性。
As the acme
extension is experimental, we’ll include {includes}/extension-status.adoc
that provides extension status text.
It uses the extension status attribute defined in the header.
Unresolved directive in doc-create-tutorial.adoc - include::{includes}/extension-status.adoc[]
现在,文档的预览应包括摘要下方的警告框,说明该插件是实验性技术,并描述了对实验性技术的稳定性和支持方面的预期。
The preview of your document should now include an admonition box below the abstract explaining that the plugin is experimental technology, and describing what can be expected in terms of stability or support for experimental technologies.
Define Prerequisites
我们需要告诉用户完成本教程所需的资源。
We need to tell users what resources are required for completing the tutorial.
任何描述开发活动的教程都应使用 {includes}/prerequisites.adoc
来确保在描述先决条件时使用一致的语言。声明 prerequisites-
属性可以自定义最终文本。
Any tutorial describing development activity should use {includes}/prerequisites.adoc
to ensure consistent language is used when describing prerequisites.
Declared prerequisites-
attributes can customize the final text.
== 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 | Declare that our hypothetical tutorial will take about 30 minutes to complete. |
2 | Declare that our nonsensical acme extension also requires a container runtime. |
3 | For simplicity in this tutorial, we will avoid GraalVM and Mandrel prerequisites. |
4 | Include the common file that provides text describing prerequisites. |
第二层 Prerequistes
标题应紧跟在文档预览中的扩展状态框之后。它应该说明:
A second level Prerequistes
heading should immediately follow the extension status box in your document preview.
It should state:
-
that this tutorial will take roughly 30 minutes
-
that you need an IDE, JDK (with versions), maven (with a placeholder for the maven version), a working container runtime, and (optionally) the Quarkus CLI.
Describe the steps for completing the tutorial
此过程有几部分。只需记住,每一步都应以一个可理解/可观察的结果结束:“输出应类似于这样……”
There are a few parts to this process. Just remember that each step should conclude with a comprehensible/observable result: "The output should look something like this…"
Define the first step
在指定第一步的头之前启用节号。
Enable section numbering before specifying the header for 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 | Create a second level heading for the first step |
3 | Describe the step briefly |
4 | Define the artifact id (Maven or Gradle) |
5 | List the extensions required by this project |
6 | Use common text to describe how to create a project |
文档预览现在应包含一个名为 1. Create a new project
的新部分,其中包含使用 Quarkus CLI 和 maven 创建新项目的步骤。
The document preview should now include a new section called 1. Create a new project
, that contains steps for creating a new project using both the Quarkus CLI and maven.
Using a source file
在本教程中,我们将使用标签包含来自单独 Java 文件的代码。
In this tutorial, we are going to include code from a separate Java file using tags.
将此看作一个有抱负的示例。通常会将来源直接包含在源代码块中。虽然包含来自 Java 文件的来源存在优势,但有关引用代码应实现的细节还待解决。欢迎提供帮助和建议! Consider this an aspirational example. Source is more commonly included directly in the source code block. While there are advantages to including source from Java files, there are details that we have to work out regarding where referenced code should live. Help and ideas are welcome! |
让我们创建一个名为 acme-serve-http-requests-MyAcmeApplication.java
的文件。虽然这不是一个有效的 Java 文件名,但它确实与我们的教程来源紧密相连。我们将依靠 IDE 的神奇功能进行语法检查。
Let’s create a file called acme-serve-http-requests-MyAcmeApplication.java
.
While this is not a valid Java file name, it does sit nicely next to our tutorial source.
We’re going to rely on IDE magic for syntax checking.
让我们向文件添加以下代码:
Let’s add the following code to that file:
// 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[]
在此代码示例中需要注意以下几点:
There are a few things to notice in this code sample:
-
AsciiDoc callouts are shown as comments on some lines, and their numbering is not sequential.
-
AsciiDoc content regions are defined by tag pairs (
tag::
andend::
) in comments surrounding different sections of code.
Provide concise subsequent steps
现在让我们指导学习者使用虚构的 @Anvil
注解创建一个简单的端点。
Let’s now instruct the learner to create a simple endpoint using the imaginary @Anvil
annotation.
Create a source code file
我们将从在文件中创建并添加端点的步骤开始。
We’ll start with the steps required to create and add an endpoint to a 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 directive in doc-create-tutorial.adoc - 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.
有关这些指令需要注意以下几点:
Some things to notice about these instructions:
-
We are including code from the source file while using Asciidoc tagged regions to exclude the
goodbye
method from the listing. -
We put some context around what
@ApplicationScoped
means, without going into details about alternative CDI lifecycles -
We describe what
@Anvil
is providing in the specific case covered by this tutorial.
在教程中提供解释时要小心。在教程中包含足够的信息,帮助用户确定他们接下来应该参考哪些其他资源 (howto
, concept
或 reference
)。
Be careful with the amount of explanation given in a tutorial.
Include enough information in the tutorial to help the user determine what other resource (howto
, concept
, or reference
) they should look at next.
预览应包含一个新章节 2. Hello, World! as an Acme REST service
,其中包含 src/main/java/org/acme/MyAcmeApplication.java
的内容,省略了 goodbye
方法。
Your preview should contain a new section, 2. Hello, World! as an Acme REST service
that includes the contents of src/main/java/org/acme/MyAcmeApplication.java
with the goodbye
method omitted.
Explore continuous development and test
现在是指导用户启动 Quarkus dev 模式的时候了。常见包括项对我们来说做了大部分工作:
It’s now time to walk the user through starting Quarkus dev mode. A common include does most of the work for us:
== Dev Mode: Hello, World!
Let's run our application using Quarkus' iterative development mode:
Unresolved directive in doc-create-tutorial.adoc - 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" 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.
我们在此提供了一些信息:
We’re providing a few things here:
-
We’re using common text that describes how to start dev mode.
-
We describe how to use
curl
to test the output of our defined endpoint.
预览应包括一个新章节,“3. Dev 模式:Hello, World!”该部分应包括使用 Quarkus dev 模式的三个方法(cli、maven 和 gradle)。它应包含包含 curl 控制台命令和输出的代码块以及退出 dev 模式的说明。
Your preview should contain a new section, "3. Dev Mode: Hello, World!" That section should include three methods of launching Quarkus dev mode (cli, maven, gradle). It should have codeblocks containing curl console commands and output, and instructions for how to exit dev mode.
Adding tests
现在,让我们引导用户向其应用程序中添加测试:
Now let’s walk users through adding a test to their application:
== 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 directive in doc-create-tutorial.adoc - 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 区域标记来从列表中排除一个方法(我们稍后会添加该方法)。
We’re using Asciidoc region tags to exclude a method from the listing (that we will be adding later).
预览应包含一个新的部分 4. Testing: Hello, World!
,其中包含 `src/main/java/org/acme/MyAcmeApplicationTest.java`的内容,但省略了 `testGoodbyeEndpoint`方法。
Your preview should contain a new section, 4. Testing: Hello, World!
that includes the contents of src/main/java/org/acme/MyAcmeApplicationTest.java
with the testGoodbyeEndpoint
method omitted.
Add additional capabilities
让我们添加另一个步骤,以使用虚拟 `@Toaster`注释创建不同的端点,并为其提供相应测试。
Let’s add another step for creating a different endpoint using the imaginary @Toaster
annotation, and for providing a corresponding test.
== 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 directive in doc-create-tutorial.adoc - 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]
Unresolved directive in doc-create-tutorial.adoc - 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.
几点注意:
A few things to note:
-
We’re using the AsciiDoc region tag to include only one region of the target file.
-
We do not go into detail explaining concepts:
-
We talk about what the
@Toaster
annotation is doing in this example. -
We define the term
Multi
in a way that helps a user find their way to other related materials (How to, Concept, or Reference).
-
预览现在应包含两个新部分,5. Goodbye, Sweet Planet! Server sent events with Acme`和 `6. Testing: Goodbye, Sweet Planet!
。
Your preview should now contain two new sections, 5. Goodbye, Sweet Planet! Server sent events with Acme
and 6. Testing: Goodbye, Sweet Planet!
.
两个新的代码列表应重点关注之前遗漏的方法:goodbye`来自 `src/main/java/org/acme/MyAcmeApplication.java
,以及 testGoodbyeEndpoint`来自 `src/main/java/org/acme/MyAcmeApplicationTest.java
。
The two new code listings should be focused on the methods that were omitted before:
goodbye
from src/main/java/org/acme/MyAcmeApplication.java
, and testGoodbyeEndpoint
from 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 | Congratulate the user on a job well done! |
预览现在应包含一个未编号的 `Summary`部分。
Your preview should now contain an unnumbered Summary
section.
Summary
恭喜!您已创建了一个教程,其中描述了如何创建使用不可理解的注释的应用程序,这些注释来自一个虚拟扩展。
Congratulations! You have created a tutorial that describes how to create an application that uses annotations of dubious merit from a hypothetical extension.
将结果与完整的操作示例进行比较:
Compare your result against the complete worked example:
Unresolved directive in doc-create-tutorial.adoc - include::{doc-examples}/acme-serve-http-requests-tutorial.adoctxt[]