演習 - Quarkus アプリケーションを作成する

完了

このユニットでは、基本的な Quarkus アプリケーションを作成します。 Maven を使用してアプリケーションをブートストラップし、任意の統合開発環境 (IDE) を使ってコードを編集します。 任意のターミナルを使用して、コードを実行します。 Docker を使ってローカル PostgreSQL Database を起動し、アプリケーションをローカルで実行してテストできるようにします。

Maven を使って Quarkus アプリケーションを生成する

Quarkus プロジェクト構造を生成するには、いくつかの方法があります。 Quarkus Web インターフェイス、IDE プラグイン、または Quarkus Maven プラグインを使用できます。 Maven プラグインを使用してプロジェクト構造を生成してみましょう。

次のいくつかの依存関係を使用して、アプリケーションを生成します。

  • REST エンドポイントを公開するための resteasy 依存関係
  • JSON をシリアル化および逆シリアル化するための jackson 依存関係
  • データベースと対話するための hibernate 依存関係
  • PostgreSQL データベースに接続するための postgresql 依存関係
  • Docker イメージをビルドするための docker 依存関係

最初にアプリケーションをローカルで実行してから、そのコンテナー化されたバージョンを Azure Container Apps にデプロイするため、Azure の依存関係を指定する必要はありません。

コマンド プロンプトで、To Do アプリケーションを生成します。

mvn -U io.quarkus:quarkus-maven-plugin:3.7.3:create \
    -DplatformVersion=3.7.3 \
    -DprojectGroupId=com.example.demo \
    -DprojectArtifactId=todo \
    -DclassName="com.example.demo.TodoResource" \
    -Dpath="/api/todos" \
    -DjavaVersion=17 \
    -Dextensions="resteasy-jackson, hibernate-orm-panache, jdbc-postgresql, docker"

このコマンドにより、新しい Quarkus プロジェクトが作成されます。 Maven ディレクトリ構造 (ソース コードの場合は src/main/java、テストの場合は src/test/java) が生成されます。 いくつかの Java クラス、いくつかのテスト、いくつかの Dockerfile が作成されます。 また、必要な依存関係 (Hibernate、RESTEasy、Jackson、PostgreSQL、Docker) をすべて含む pom.xml ファイルも生成されます。

  <dependencies>
    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-hibernate-orm-panache</artifactId>
    </dependency>
    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-resteasy-jackson</artifactId>
    </dependency>
    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-jdbc-postgresql</artifactId>
    </dependency>
    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-container-image-docker</artifactId>
    </dependency>
    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-arc</artifactId>
    </dependency>
    <dependency>
        <groupId>io.quarkus</groupId>
        <artifactId>quarkus-hibernate-orm</artifactId>
    </dependency>
    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-resteasy</artifactId>
    </dependency>
    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-junit5</artifactId>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>io.rest-assured</groupId>
      <artifactId>rest-assured</artifactId>
      <scope>test</scope>
    </dependency>
  </dependencies>

Note

pom.xml ファイル内のすべての依存関係は、Quarkus BOM (部品表) io.quarkus.platform:quarkus-bom で定義されています。

アプリケーションをコーディングする

次に、生成された MyEntity.java クラスの名前を Todo.java に変更します (TodoResource.java ファイルと同じフォルダーにあります)。 既存のコードを次の Java コードに置き換えます。 PostgreSQL サーバーとの間でデータの格納と取得を行うために、Java Persistence API (jakarta.persistence.* パッケージ) が使用されます。 また、永続化レイヤーを簡略化するために、Hibernate ORM with Panache (io.quarkus.hibernate.orm.panache.PanacheEntity から継承) が使用されます。

JPA エンティティ (@Entity) を使用して、Java Todo オブジェクトを PostgreSQL Todo テーブルに直接マップします。 その後、TodoResource REST エンドポイントによって新しい Todo エンティティ クラスが作成され、保持されます。 このクラスは、Todo テーブルでマップされているドメイン モデルです。 テーブルは JPA によって自動的に作成されます。

PanacheEntity を拡張して、型に対して汎用の作成、読み取り、更新、削除 (CRUD) の複数のメソッドを取得します。 そのため、1 行の Java コードだけで Todo オブジェクトの保存や削除などを行うことができます。

次のコードを Todo エンティティに追加します。

package com.example.demo;

import io.quarkus.hibernate.orm.panache.PanacheEntity;

import jakarta.persistence.Entity;
import java.time.Instant;

@Entity
public class Todo extends PanacheEntity {

    public String description;

    public String details;

    public boolean done;

    public Instant createdAt = Instant.now();

    @Override
    public String toString() {
        return "Todo{" +
                "id=" + id + '\'' +
                ", description='" + description + '\'' +
                ", details='" + details + '\'' +
                ", done=" + done +
                ", createdAt=" + createdAt +
                '}';
    }
}

そのクラスを管理するには、TodoResource を更新し、HTTP を使用してデータを格納および取得するための REST インターフェイスを公開できるようにします。 TodoResource クラスを開き、コードを以下と置き換えます。

package com.example.demo;

import jakarta.inject.Inject;
import jakarta.transaction.Transactional;
import jakarta.ws.rs.Consumes;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import static jakarta.ws.rs.core.MediaType.APPLICATION_JSON;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.core.UriBuilder;
import jakarta.ws.rs.core.UriInfo;
import org.jboss.logging.Logger;

import java.util.List;

@Path("/api/todos")
@Consumes(APPLICATION_JSON)
@Produces(APPLICATION_JSON)
public class TodoResource {

    @Inject
    Logger logger;

    @Inject
    UriInfo uriInfo;

    @POST
    @Transactional
    public Response createTodo(Todo todo) {
        logger.info("Creating todo: " + todo);
        Todo.persist(todo);
        UriBuilder uriBuilder = uriInfo.getAbsolutePathBuilder().path(todo.id.toString());
        return Response.created(uriBuilder.build()).entity(todo).build();
    }

    @GET
    public List<Todo> getTodos() {
        logger.info("Getting all todos");
        return Todo.listAll();
    }
}

アプリケーションの実行

アプリケーションを開発モードで実行する場合は、Docker が実行されている必要があります。 これは、Quarkus によって PostgreSQL データベースが必要であることが検出され (pom.xml ファイルで PostgreSQL 依存関係 quarkus-jdbc-postgresql が宣言されているため)、PostgreSQL Docker イメージがダウンロードされ、データベースを使ってコンテナーが起動されるためです。 その後、データベースに Todo テーブルが自動的に作成されます。

お使いのマシンのローカルで Docker が実行されていることを確認し、次のコマンドを使って To Do アプリケーションを実行します。

cd todo
./mvnw quarkus:dev    # On Mac or Linux
mvnw.cmd quarkus:dev  # On Windows

Quarkus アプリケーションが起動し、データベースに接続されるはずです。 次の出力が表示されます。

[io.qua.dat.dep.dev.DevServicesDatasourceProcessor] Dev Services for the default datasource (postgresql) started.
[io.qua.hib.orm.dep.HibernateOrmProcessor] Setting quarkus.hibernate-orm.database.generation=drop-and-create to initialize Dev Services managed database
__  ____  __  _____   ___  __ ____  ______ 
 --/ __ \/ / / / _ | / _ \/ //_/ / / / __/ 
 -/ /_/ / /_/ / __ |/ , _/ ,< / /_/ /\ \   
--\___\_\____/_/ |_/_/|_/_/|_|\____/___/   
[org.hib.eng.jdb.spi.SqlExceptionHelper] (JPA Startup Thread) SQL Warning Code: 0, SQLState: 00000

[org.hib.eng.jdb.spi.SqlExceptionHelper] (JPA Startup Thread) table "todo" does not exist, skipping
[org.hib.eng.jdb.spi.SqlExceptionHelper] (JPA Startup Thread) SQL Warning Code: 0, SQLState: 00000
[org.hib.eng.jdb.spi.SqlExceptionHelper] (JPA Startup Thread) sequence "hibernate_sequence" does not exist, skipping
[io.quarkus] (Quarkus Main Thread) todo 1.0.0-SNAPSHOT on JVM (powered by Quarkus) started in 4.381s. Listening on: http://localhost:8080
[io.quarkus] (Quarkus Main Thread) Profile dev activated. Live Coding activated.
[io.quarkus] (Quarkus Main Thread) Installed features: [agroal, cdi, hibernate-orm, hibernate-orm-panache, jdbc-postgresql, narayana-jta, resteasy, resteasy-jackson, smallrye-context-propagation, vertx]

--
Tests paused
Press [r] to resume testing, [o] Toggle test output, [:] for the terminal, [h] for more options>

アプリケーションをテストするには、cURL を使用します。

別のターミナルで、次のコマンドを使用して、データベースに新しい To Do アイテムを作成します。 Quarkus コンソールにログが表示されるはずです。

curl --header "Content-Type: application/json" \
    --request POST \
    --data '{"description":"Take Quarkus MS Learn","details":"Take the MS Learn on deploying Quarkus to Azure Container Apps","done": "true"}' \
    http://127.0.0.1:8080/api/todos

このコマンドでは、(識別子を持つ) 作成されたアイテムが返されるはずです。

{"id":1,"description":"Take Quarkus MS Learn","details":"Take the MS Learn on deploying Quarkus to Azure Container Apps","done":true,"createdAt":"2022-12-30T15:17:20.280203Z"}

次の cURL コマンドを使って、2 つ目の To Do を作成します。

curl --header "Content-Type: application/json" \
    --request POST \
    --data '{"description":"Take Azure Container Apps MS Learn","details":"Take the ACA Learn module","done": "false"}' \
    http://127.0.0.1:8080/api/todos

次に、新しい cURL 要求を使用してデータを取得します。

curl http://127.0.0.1:8080/api/todos

このコマンドでは、作成したアイテムを含め、To Do アイテムのリストが返されます。

[ 
  {"id":1,"description":"Take Quarkus MS Learn","details":"Take the MS Learn on deploying Quarkus to Azure Container Apps","done":true},
  {"id":2,"description":"Take Azure Container Apps MS Learn","details":"Take the ACA Learn module","done":false}
]

アプリケーションをテストする

アプリケーションをテストするために、既存の TodoResourceTest クラスを使用できます。 ここで REST エンドポイントをテストする必要があります。 エンドポイントをテストするには、RESTAssured を使います。 TodoResourceTest クラスのコードを、次のコードに置き換えます。

package com.example.demo;

import io.quarkus.test.junit.QuarkusTest;
import static io.restassured.RestAssured.given;
import static jakarta.ws.rs.core.HttpHeaders.CONTENT_TYPE;
import static jakarta.ws.rs.core.MediaType.APPLICATION_JSON;
import org.junit.jupiter.api.Test;

@QuarkusTest
class TodoResourceTest {

    @Test
    void shouldGetAllTodos() {
        given()
                .when().get("/api/todos")
                .then()
                .statusCode(200);
    }

    @Test
    void shouldCreateATodo() {
        Todo todo = new Todo();
        todo.description = "Take Quarkus MS Learn";
        todo.details = "Take the MS Learn on deploying Quarkus to Azure Container Apps";
        todo.done = true;

        given().body(todo)
                .header(CONTENT_TYPE, APPLICATION_JSON)
                .when().post("/api/todos")
                .then()
                .statusCode(201);
    }
}

アプリケーションをテストする場合、Docker Desktop が実行されている必要があります。これは、テストに PostgreSQL Database が必要であることが Quarkus によって検出されるためです。 次のコマンドを使ってアプリケーションをテストします。

./mvnw clean test    # On Mac or Linux
mvnw.cmd clean test  # On Windows

次のような出力が表示されるはずです。

[INFO] -------------------------------------------------------
[INFO]  T E S T S
[INFO] -------------------------------------------------------
[INFO] Running com.example.demo.TodoResourceTest
[INFO] 
[INFO] Results:
[INFO] 
[INFO] Tests run: 2, Failures: 0, Errors: 0, Skipped: 0
[INFO] 
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------