練習 - 建立 Quarkus 應用程式

已完成

在此單元中,您會建立基本的 Quarkus 應用程式。 您可以使用 Maven 來啟動應用程式,以及您選擇的整合開發環境 (IDE) 來編輯程式代碼。 使用所選的終端機來執行該程式碼。 您可以使用 Docker 來啟動本機 PostgreSQL 資料庫,讓您可以在本機執行及測試應用程式。

使用 Maven 產生 Quarkus 應用程式

有數種方式可以產生 Quarkus 項目結構。 您可以使用 Quarkus Web 介面、IDE 外掛程式或 Quarkus Maven 外掛程式。 讓我們使用 Maven 外掛程式來產生項目結構。

您會產生具有數個相依性的應用程式:

  • 要公開 REST 端點的 resteasy 相依性
  • 用於序列化和反序列化 JSON 的jackson 依賴性
  • 要與資料庫互動的 hibernate 相依性
  • 要連線到 PostgreSQL 資料庫的 postgresql 相依性
  • 要建置 Docker 映射的 docker 相依性

您不需要指定 Azure 相依性,因為您必須先在本機執行應用程式,然後將其容器化版本部署到 Azure Container Apps。

在命令提示字元中,建立待辦事項應用程式:

mvn -U io.quarkus:quarkus-maven-plugin:3.19.0:create \
    -DplatformVersion=3.18.4 \
    -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 類別、一些測試,以及一些 Dockerfiles。 它也會產生具有所有所需相依性的 pom.xml 檔案(Hibernate、RESTEasy、Jackson、PostgreSQL 和 Docker):

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

備註

pom.xml 檔案中的所有相依性都會定義在 Quarkus BOM(材料帳單)io.quarkus.platform:quarkus-bom中。

撰寫應用程式程序代碼

接下來,將產生的 MyEntity.java 類別重新命名為 Todo.java(位於與 TodoResource.java 檔案相同的資料夾中)。 以下列 Java 程式代碼取代現有的程式代碼。 它會使用 Java Persistence API (jakarta.persistence.* 套件)從 PostgreSQL 伺服器儲存和擷取數據。 它也使用Hibernate ORM 搭配 Panache(繼承自io.quarkus.hibernate.orm.panache.PanacheEntity),以簡化資料持久層。

您可以使用 JPA 實體 (@Entity) 將 Java Todo 物件直接對應至 PostgreSQL Todo 資料表。 TodoResource REST 端點接著會建立新的 Todo 實體類別,並加以保存。 這個類別是在 Todo 資料表上對應的網域模型。 JPA 會自動建立數據表。

擴充 PanacheEntity 可讓您取得您類型的一些泛型建立、讀取、更新和刪除 (CRUD) 方法。 因此,您可以在一行 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,以便發行 REST 介面以使用 HTTP 儲存和擷取數據。 開啟 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 資料庫(因為 postgreSQL 相依性 quarkus-jdbc-postgresqlpom.xml 檔案中宣告),下載 PostgreSQL Docker 映射,並使用資料庫啟動容器。 然後,它會自動在資料庫中建立 Todo 數據表。

請確定 Docker 已在本機電腦上執行,並使用此命令執行 to-do 應用程式:

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

Quarkus 應用程式應該會啟動並連線到您的資料庫。 您應該會看到下列輸出:

2025-02-28 08:38:33,418 INFO  [io.qua.dat.dep.dev.DevServicesDatasourceProcessor] (build-28) Dev Services for default datasource (postgresql) started - container ID is ce37977203b0
2025-02-28 08:38:33,421 INFO  [io.qua.hib.orm.dep.dev.HibernateOrmDevServicesProcessor] (build-6) Setting quarkus.hibernate-orm.database.generation=drop-and-create to initialize Dev Services managed database
__  ____  __  _____   ___  __ ____  ______ 
 --/ __ \/ / / / _ | / _ \/ //_/ / / / __/ 
 -/ /_/ / /_/ / __ |/ , _/ ,< / /_/ /\ \   
--\___\_\____/_/ |_/_/|_/_/|_|\____/___/   
2025-02-28 08:38:35,278 INFO  [io.quarkus] (Quarkus Main Thread) todo 1.0.0-SNAPSHOT on JVM (powered by Quarkus 3.18.4) started in 5.367s. Listening on: http://localhost:8080

2025-02-28 08:38:35,280 INFO  [io.quarkus] (Quarkus Main Thread) Profile dev activated. Live Coding activated.
2025-02-28 08:38:35,280 INFO  [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 [e] to edit command line args (currently ''), [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":"2025-02-26T07:27:30.093447Z"}

使用下列 cURL 命令建立第二個 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

這個指令會傳回待辦事項的清單,包括您建立的項目:

[ 
  {"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 必須執行,因為 Quarkus 偵測到它需要 PostgreSQL 資料庫進行測試。 使用此指令測試應用程式:

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