The English version of quarkus.io is the official project site. Translated sites are community supported on a best-effort basis.

エクステンション Codestart

このガイドでは、エクステンションのために Quarkus Codestart を作成および設定する方法について説明します。

説明

"エクステンション Codestart"は、Quarkusのエクステンションクイックスタートコード生成システムに付けられた名前です。このシステムは、Quarkus の使用開始時にパーソナライズされた体験を提供することを目的としています。 Quarkus のエクステンションは、そのエクステンションを使い始めるために必要な/推奨されるリソースやコードを含む、1つまたは複数の明確に定義された Codestart を提供することができます。

エクステンション Codestart は、Quarkus ツールを使用するときにデフォルトで適用されます (選択したエクステンションに含まれている場合)。

  • code.quarkus.io([code]とタグ付けされたエクステンションを探す)

  • Quarkus Maven プラグイン:

    mvn io.quarkus.platform:quarkus-maven-plugin:create
  • Quarkus CLI

    quarkus create app

動作原理

プロジェクトを開始する際には、言語、ビルドツール、フレームワークを選択し、Dockerfile、CI、依存関係、コードを追加していきます。

Codestart は、プロジェクトの生成に貢献する際に同じように働き、2つのカテゴリーに分けられます。

"ベース" のコードスタート(この組み合わせを選択):

  • project: プロジェクトの骨組(例:Quarkusプロジェクト)

  • buildtool: ビルドツール(例:Maven、Gradle、Gradle with Kotlin DSL)

  • language: コーディング言語(例:Java、Kotlin、Scala)

  • config: 設定の種類(例:yaml、properties)

追加の Codestart (必要に応じて、基本コードの上に追加):

  • tooling:プロジェクトを改善するために追加できるもの(例: Dockerfiles、GitHub Actions など)

  • code: どのQuarkusエクステンションもスターターコードを提供可能です。ユーザーはそれを有効にするかどうかを決めることができます。

各 Codestart は以下から構成されています:

  1. Codestartのユニークな名前、つまり my-codestart

  2. Codestartファイルを置くディレクトリ、つまり my-codestart/

  3. codestart.yml ファイル

  4. 共通の構造と命名規則に従ったいくつかのテンプレート(オプション)

Quarkus Extension の Codestart はどこにありますか?

  • Quarkus のコアレポジトリでは、エクステンションの Codestart はすべて同じ モジュール に入っています。

  • Quarkus REST(旧RESTEasy Reactive)、RESTEasy、Spring Webエクステンションのコードスタートは、 基本コードスタート の一部です。

  • その他のエクステンションの場合、Codestartは通常、ランタイム・モジュールに配置されます(別の Codestart アーティファクトを生成するよう、 pom.xml に特別な指示があります)。

ベース Codestart

ベース Codestart には、プロジェクト、ビルドツール、言語、設定、ツールファイルを作成するためのテンプレートが含まれています。

さらに、Quarkusには、コードスタートで新しいエクステンションプロジェクトを初期化する次のような方法も用意されています。

コマンドラインインタフェース

Codestartのスケルトンで新しいエクステンションを作成するには、 create extension コマンドに --codestart フラグを指定します。

quarkus create extension --codestart org.acme:greeting-extension
Detected layout type is 'standalone'
Generated runtime artifactId is 'greeting-extension'


applying codestarts...
📚  java
🔨  maven
📦  quarkus-extension
🚀  devmode-test
🚀  extension-base
🚀  extension-codestart
🚀  integration-tests
🚀  unit-test

-----------
 👍  extension has been successfully generated in:
--> /Users/.../greeting-extension
-----------
Navigate into this directory and get started: quarkus build

Quarkus CLIのインストール方法や使用方法については、 Quarkus CLIガイド を参照してください。

Maven

Quarkusは、エクステンションプロジェクトを初期化するために、 create-extension Maven Mojo を提供します。

Codestartスケルトンで新しいエクステンションを生成するには、このMojoに -DwithCodestart フラグを指定します。

mvn io.quarkus.platform:quarkus-maven-plugin:3.9.3:create-extension -N \
    -DgroupId=org.acme \
    -DextensionId=greeting-extension \
    -DwithCodestart
[INFO] --- quarkus-maven-plugin:3.9.3:create-extension (default-cli) @ standalone-pom ---

Detected layout type is 'standalone'
Generated runtime artifactId is 'greeting-extension'


applying codestarts...
📚  java
🔨  maven
📦  quarkus-extension
🚀  devmode-test
🚀  extension-base
🚀  extension-codestart
🚀  integration-tests
🚀  unit-test

-----------
 👍  extension has been successfully generated in:
--> /Users/.../greeting-extension
-----------
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  1.638 s
[INFO] Finished at: 2022-10-24T21:27:51+02:00
[INFO] ------------------------------------------------------------------------

エクステンション Codestart の作成

以下は、エクステンション Codestart を作成するためのステップバイステップのガイドです。 Quarkus Insight #99 のライブコーディングセッションもご覧ください。

前述したように、プロジェクトの基本ファイル (pom.xml、Dockerfile など) は、Quarkus コアが提供するベース Codestart ですでに生成されています。このおかげで、エクステンションのスターターコードにのみ集中することができます。

エクステンション GAV の例として io.quarkiverse.aloha:quarkus-aloha を見てみましょう (このエクステンションは存在しませんので探さないでください)。

コード

Codestart は、新しいプロジェクトの足場を作るためのテンプレートです。

このチュートリアルでは、Quarkus プロジェクトから Codestart プロジェクトを作成し、必要なテンプレートを追加します。

したがって、 code.quarkus.io に移動し、aloha エクステンションとグループとして org.acme を使用して新しいプロジェクトを作成します (つまり、 パッケージ名の org.acme プレースホルダー )。素敵なスターターを用意してください。ビジネスロジックを含める必要はありません。代わりに、コンパイルしてエクステンションの使用方法の概要を示すスタブデータ/Hello World を含める必要があります。このアイデアは、エクステンションの最も一般的な開始点となるコードを提供することにあります。

コードに満足していますか? そこから Codestart を作成しましょう。

Codestart (Quarkiverse またはスタンドアロンエクステンション)

エクステンションの中で:

  • runtime/src/main/codestarts/quarkus/aloha-codestart ディレクトリーを作成します

  • src/main/java を、生成されたプロジェクトから runtime/src/main/codestarts/quarkus/aloha-codestart/java/src/main/java に移動します

  • (オプション) この規約でコンフィグを移動します: アプリケーション設定 application.yml

  • codestart.yml runtime/src/main/codestarts/quarkus/aloha-codestart でのファイルの作成:

    name: aloha-codestart
    ref: aloha
    type: code
    tags: extension-codestart
    metadata:
      title: Aloha
      description: Start to code with the Aloha extension.
      related-guide-section: https://quarkiverse.github.io/quarkiverse-docs/quarkus-aloha/dev/
      path: /aloha # (optional) for web extensions providing HTTP resources
  • Maven ビルドプラグイン設定を runtime/pom.xml に追加します (Codestart アーティファクトを生成するには: /target/quarkus-aloha-VERSION-codestarts.jar ):

          <plugin>
            <artifactId>maven-jar-plugin</artifactId>
            <executions>
              <execution>
                <id>generate-codestart-jar</id>
                <phase>generate-resources</phase>
                <goals>
                  <goal>jar</goal>
                </goals>
                <configuration>
                  <classesDirectory>${project.basedir}/src/main</classesDirectory>
                  <includes>
                    <include>codestarts/**</include>
                  </includes>
                  <classifier>codestarts</classifier>
                  <skipIfEmpty>true</skipIfEmpty>
                </configuration>
              </execution>
            </executions>
          </plugin>
  • エクステンションメタデータ runtime/src/main/resources/META-INF/quarkus-extension.yaml に Codestart バインディングを追加します。 これがないと、エクステンションが選択されたときに Codestart が追加されません :

    name: ...
    description: ...
    metadata:
      ...
      codestart:
        name: "aloha"
        languages:
        - "java"
        artifact: "io.quarkiverse.aloha:quarkus-aloha:codestarts:jar:${project.version}"
  • README.md base/README.tpl.qute.md のセクションテンプレートに readme を追加します:

    {#include readme-header /}
  • エクステンションのルート (または単に runtime ) で mvn clean install を実行します。

  • これで、エクステンションを使用するプロジェクトを作成して、Codestart が実際に機能することを確認できます (スナップショットのバージョンが正しいことを確認してください)。

    quarkus create app aloha-app -x=io.quarkiverse.aloha:quarkus-aloha:999-SNAPSHOT
    
    ...
    applying codestarts...
    📚  java
    🔨  maven
    📦  quarkus
    📝  config-properties
    🔧  dockerfiles
    🔧  maven-wrapper
    🚀  aloha-codestart <<<<<<<<<<<<<<<<
    ...

テスト

  • この依存関係を integration-tests に追加します。

    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-devtools-testing</artifactId>
      <scope>test</scope>
    </dependency>
  • integration-testsAlohaCodestartTest を作成します。

    public class AlohaCodestartTest {
    
        @RegisterExtension
        public static QuarkusCodestartTest codestartTest = QuarkusCodestartTest.builder()
                .languages(Language.JAVA)
                .setupStandaloneExtensionTest("io.quarkiverse.aloha:quarkus-aloha")
                .build();
    
        @Test
        void testContent() throws Throwable {
            codestartTest.checkGeneratedSource("org.acme.AlohaResource");
        }
    
        @Test
        void buildAllProjects() throws Throwable {
            codestartTest.buildAllProjects();
        }
    }

さらに詳しく

  • エクステンションが Web リソースを提供する場合は、base/src/main/resources/META-INF/resources/index.entry.qute.html テンプレート (index.htmlとWebエクステンションの Codestart) を追加します。

  • 別の言語を追加します (Java と Kotlin を提供することをお勧めします)。

  • 他のリソースを追加することもできます (言語固有でない場合は、./base ディレクトリーに)。

Quarkus Coreのエクステンション Codestart

  • Codestart はすべて 特定のモジュール のグループにあります。

  • 追加の Maven 設定は必要ありません。

  • エクステンションメタデータ は、すべてのコア・コードスタートを含むアーティファクトを参照します。

  • また、テストは グループ化 されています。ビルドのテストは、それ専用のグループ化された テスト があるので、必要ありません。例えば

    public class ConfigYamlCodestartTest {
    
        @RegisterExtension
        public static QuarkusCodestartTest codestartTest = QuarkusCodestartTest.builder()
                .codestarts("config-yaml")
                .languages(JAVA, KOTLIN)
                .build();
    
        @Test
        void testContent() throws Throwable {
            codestartTest.checkGeneratedSource("org.acme.GreetingConfig");
            codestartTest.assertThatGeneratedFileMatchSnapshot(JAVA, "src/main/resources/application.yml");
        }
    
        @Test
        @EnabledIfSystemProperty(named = "build-projects", matches = "true")
        void buildAllProjectsForLocalUse() throws Throwable {
            codestartTest.buildAllProjects();
        }
    
    }

具体的なトピック

パッケージ名の org.acme プレースホルダー

エクステンションの Codestart のソースでは、パッケージ名として org.acme を使用する必要があります。生成されたプロジェクトでは、ユーザーが指定したパッケージが使用されます (そして、 org.acme を自動的に置き換えます)。

パッケージは、すべてのソースファイル (.java、.kt、.scala) で自動的に置換されます。パッケージのディレクトリーも自動的に調整されます。もし、何らかの理由で、他のタイプのファイルがユーザーパッケージ名を必要とする場合、そのファイルおよび {project.package-name} データプレースホルダー (grpc proto ファイルにおけるサンプル). に テンプレート(Qute) を使用すべきです。

codestart.yml

# codestart unique name
name: resteasy-example
# codestart reference, use the extension id
ref: resteasy
# use 'code' (other types are for base codestarts)
type: code
# use 'extension-codestart'
tags: extension-codestart
# public metadata for this example (accessible as data in the templates e.g. {title})
metadata:
  title: RESTEasy Jakarta REST example
  description: Rest is easy peasy with this Hello World RESTEasy resource.
  related-guide-section: https://quarkus.io/guides/getting-started#the-jax-rs-resources
  # (optional) use this in web extensions with a specific path (and also add the index page)
  path: /some-path

ディレクトリ構造

codestart.yml は唯一の必須ファイルです。
  • codestart.yml は Codestart のルートに配置される必要があります。

  • ./base には、指定された言語とは無関係に処理されるすべてのファイルが含まれます

  • ./[java/kotlin/scala] は、指定された言語が選択されている場合にのみ処理されるすべてのファイルを含みます(baseをオーバーライドします)

Codestart の動的設定キー

gen-info.time = generation time (in milliseconds)
input.selected-extensions[].name|description|guide = list of selected extensions with info
input.selected-extensions-ga = Set of Strings containing the list of extensions groupId:artifactId, useful for dynamic codestarts depending on selected extensions
input.provided-code[].name|tags|title|description|related-guide: list of selected codestarts with info

Codestart の静的設定キー

quarkus.platform.group-id = BOM groupId
quarkus.platform.artifact-id = BOM artifactId
quarkus.platform.version = BOM version
project.group-id = Project groupId
project.artifact-id = Project artifactId
project.version = Project version
project.name = Project name (if specified)
project.description = Project description (if specified)
project.package-name = Project package name
quarkus.maven-plugin.group-id = Quarkus Maven plugin groupId
quarkus.maven-plugin.artifact-id = Quarkus Maven plugin artifactId
quarkus.maven-plugin.version = Quarkus Maven plugin version
quarkus.gradle-plugin.id = Quarkus Gradle pluginId
quarkus.gradle-plugin.version = Quarkus Gradle plugin version
quarkus.version = Quarkus version
java.version = Java version
kotlin.version = Kotlin version
scala.version = Scala version
scala-maven-plugin.version = Scala Maven plugin version
maven-compiler-plugin.version = Maven compiler plugin version
maven-surefire-plugin.version = Maven Surefire plugin version

ファイルの命名規則

  • .tpl.qute は、Quteで処理され、データを使用することができます(出力ファイル名から .tpl.qute が削除されます)。

  • readme.md , src/main/resources/application.yml , src/main/resources/META-INF/resources/index.html などの特定の共通ファイルは、プロジェクトに対して選択された Codestart で見つかった収集済みフラグメントから生成されます。

  • 他のファイルはコピーされます。

テンプレート(Qute)

Codestartは、ダイナミックレンダリングのために Qute テンプレート MyClass.tpl.qute.java を使用することができます。

これらのテンプレートは、以下を含むデータを使用することができます:

  • 生成するCodestartの data (および公開 metadata )( codestart.yml で指定されている)

  • プロジェクトの生成に使用されたすべてのCodestartから shared-data をマージしたもの

  • ユーザー入力

  • いくつかの動的に生成されたデータ(例: dependenciestest-dependencies

README.md

base ディレクトリに README.mdREADME.tpl.qute.md を追加することが出来ます。他のものに追加されます。つまり、エクステンション codestart に関連する情報を追加するだけです。

base/README.tpl.qute.md

{#include readme-header /}

[Optionally, Here you may add information about how to use the example, settings, ...]
{#include readme-header /} は、Quarkus プロジェクトの Codestart にある、 codestart.yml メタデータから標準的な情報を表示するテンプレートを使用することになります。

アプリケーション設定 application.yml

慣習として、Quarkusの設定は常にyamlファイル( base/src/main/resources/application.yml)として提供する必要があります。

次のようになります:

  • 他のエクステンション Codestart の設定とマージされます

  • 選択されたエクステンションに応じて、生成時に選択された設定タイプ(yamlまたはproperties)に自動的に変換されます

index.htmlとWebエクステンションの Codestart

エクステンションの Codestart では、このファイルを追加することで、生成されるindex.htmlにスニペットを提供することができます。

base/src/main/resources/META-INF/resources/index.entry.qute.html:

{#include index-entry /}
{#include index-entry /} は、Quarkus プロジェクトの Codestart にある、 codestart.yml メタデータから標準的な情報を表示するテンプレートを使用することになります。

統合テスト

エクステンションの Codestart をテストするためのエクステンション QuarkusCodestartTest が利用可能です。

<dependency>
  <groupId>io.quarkus</groupId>
  <artifactId>quarkus-devtools-testing</artifactId>
  <scope>test</scope>
</dependency>

以下をテストする方法を提供します。

  • スナップショットテストを用いて、生成されたプロジェクトコンテンツ(不変のモックデータを含む)

  • 生成されたプロジェクトのビルド/実行(実データを使用)、およびビルドを実行するためのヘルパー

すべてのテストの前に、このエクステンションは、指定された言語で、指定されたCodestartで、モックされたデータと実際のデータを使ってQuarkusプロジェクトを生成します。生成されたプロジェクトは、 target/quarkus-codestart-test ディレクトリにあります。 real-data のプロジェクトは IDE で開くことができますし、ターミナルで操作することもできます。 実データは、エクステンションCodestartの開発を繰り返し行う最も簡単な方法です。

このエクステンションは、プロジェクトのビルド buildAllProjects や、特定の言語のプロジェクト buildProject (Language language) をテストするヘルパーを提供します。また、 スナップショットテスト でコンテンツをテストするヘルパーも提供しています。

ConfigYamlCodestartTestは、Quarkus coreにおける良い例です。

スナップショットテスト

スナップショット テストとは、テストによって生成されるコンテンツが、あるリビジョンから別のリビジョン、つまりコミット間で変更されないようにする方法です。つまり、コミットごとに生成されるコンテンツは、不変であり、決定性がある必要があります(これが、モックされたデータを使用する理由です)。このようなチェックを行うために、生成されたコンテンツのスナップショットを自動生成し、後続のテスト実行時に期待される出力の参照先としてコミットします。テンプレートが変更された場合は、生成されたスナップショットの変更もコミットします。このようにして、レビューの際には、適用されたコードの変更が、生成された出力に対して期待される効果を持つことを確認することができます。

エクステンションは、コンテンツをチェックするためのヘルパーを提供します:

  • checkGeneratedSource() は、すべての言語(または特定の言語)のスナップショットに対してクラスを検証します。

  • checkGeneratedTestSource() は、すべての言語(または特定の言語)のスナップショットに対してテストクラスを検証します。

  • assertThatGeneratedFileMatchSnapshot() は、プロジェクトファイルをスナップショットと照合します。

  • 上記のメソッドの戻り値に AbstractPathAssert.satisfies(checkContains("some content")) または任意の Path アサートを使用して、ファイルに特定のコンテンツが含まれているかどうかを確認することもできます。

  • assertThatGeneratedTreeMatchSnapshots() では、特定の言語のプロジェクトのファイル構造(ツリー)を、そのスナップショットと比較することができます。

ローカルファイルシステム上の既存のスナップショットファイルを最初に生成または更新するためには、Codestartの開発中にローカルでテストを実行する際に、 -Dsnap を追加する必要があります。これらはコミットの一部として追加する必要があり、そうしないとCI上でテストが通過しません。

作成のコツ

  • あなたのエクステンションCodestartは、buildtoolやdockerfilesから独立していなければなりません/しなければなりません。

  • エクステンションCodestartは、互いに干渉することなく(組み合わせて)一緒に使えるべきです。

  • クラス名がすべてのエクステンションのCodestartでユニークであることを担保してください。

  • パッケージ名には org.acme のみを使用してください。

  • RESTのパスには、ユニークなパス /[unique] を使用してください。

  • 設定は src/main/resources/application.yml ymlに記述してください。

    これは、他の Codestart のコンフィグとマージされ、選択された設定タイプ (yaml または properties) に自動的に変換されます。

  • javaから始めて、後で別のPRでkotlinを追加することもできます(忘れないようにissueを作成してください)。

  • 質問がある場合は、 https://quarkusio.zulipchat.com/ で @ia3andy に ping してください。

関連コンテンツ