Übung – Erstellen einer Quarkus-Anwendung

Abgeschlossen

In dieser Einheit erstellen Sie eine einfache Quarkus-Anwendung. Sie verwenden Maven, um die Anwendung und eine integrierte Entwicklungsumgebung (IDE) Ihrer Wahl zu bootstrapieren, um den Code zu bearbeiten. Zum Ausführen des Codes können Sie ein beliebiges Terminal verwenden. Sie verwenden Docker, um eine lokale PostgreSQL-Datenbank zu starten, damit Sie die Anwendung lokal ausführen und testen können.

Generieren Sie die Quarkus-Anwendung mithilfe von Maven

Es gibt mehrere Möglichkeiten, eine Projektstruktur von Quarkus zu generieren. Sie können die Aspxus-Webschnittstelle, ein IDE-Plug-In oder das Aspxus Maven-Plug-In verwenden. Verwenden wir das Maven-Plug-In, um die Projektstruktur zu generieren.

Sie generieren Ihre Anwendung mit mehreren Abhängigkeiten:

  • Der resteasy-Abhängigkeit, um einen REST-Endpunkt verfügbar zu machen
  • Die jackson Abhängigkeit zum Serialisieren und Deserialisieren von JSON
  • Die hibernate-Abhängigkeit für die Interaktion mit der Datenbank
  • Die postgresql Abhängigkeit zum Herstellen einer Verbindung mit der PostgreSQL-Datenbank
  • Die docker Abhängigkeit zum Erstellen eines Docker-Images

Sie müssen keine Azure-Abhängigkeiten angeben, da Sie Ihre Anwendung zuerst lokal ausführen und dann eine containerisierte Version davon in Azure-Container-Apps bereitstellen.

Generieren Sie an einer Eingabeaufforderung die To-Do-Anwendung:

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"

Mit diesem Befehl wird ein neues Quarkus-Projekt erstellt. Es generiert eine Maven-Verzeichnisstruktur (src/main/java für Quellcode und src/test/java für Tests). Es erstellt einige Java-Klassen, einige Tests und einige Dockerfiles. Außerdem wird eine pom.xml Datei mit allen erforderlichen Abhängigkeiten generiert (Hibernate, RESTEasy, Jackson, PostgreSQL und 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>

Hinweis

Alle Abhängigkeiten in der Datei pom.xml werden in der Quarkus BOM (Stückliste) io.quarkus.platform:quarkus-bom definiert.

Codieren der Anwendung

Benennen Sie als Nächstes die generierte MyEntity.java-Klasse in Todo.java um (befindet sich im selben Ordner wie die TodoResource.java Datei). Ersetzen Sie den vorhandenen Code durch den folgenden Java-Code. Es verwendet die Java-Persistenz-API (jakarta.persistence.*-Paket), um Daten von Ihrem PostgreSQL-Server zu speichern und abzurufen. Außerdem wird Hibernate ORM with Panache (geerbt von io.quarkus.hibernate.orm.panache.PanacheEntity) verwendet, um die Persistenzebene zu vereinfachen.

Sie verwenden eine JPA-Entität (@Entity), um das Java-Todo-Objekt direkt der PostgreSQL-Todo-Tabelle zuzuordnen. Der TodoResource REST-Endpunkt erstellt dann eine neue Todo Entitätsklasse und speichert sie. Bei dieser Klasse handelt es sich um ein Domänenmodell, das in der Todo-Tabelle zugeordnet ist. Die Tabelle wird automatisch von JPA erstellt.

Wenn Sie PanacheEntity erweitern, erhalten Sie eine Reihe generischer Erstellungs-, Lese-, Aktualisierungs- und Löschmethoden (CRUD) für Ihren Typ. Sie können also Dinge wie speichern und löschen Todo Objekte in nur einer Zeile Java-Code.

Fügen Sie der entität Todo den folgenden Code hinzu:

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 +
                '}';
    }
}

Um diese Klasse zu verwalten, aktualisieren Sie die TodoResource, damit sie REST-Schnittstellen veröffentlichen kann, um Daten mithilfe von HTTP zu speichern und abzurufen. Öffnen Sie die TodoResource Klasse, und ersetzen Sie den Code durch Folgendes:

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();
    }
}

Ausführen der Anwendung

Wenn Sie die Anwendung im Entwicklungsmodus ausführen, muss Docker ausgeführt werden. Das liegt daran, dass Ctrlus erkennt, dass Sie eine PostgreSQL-Datenbank benötigen (aufgrund der im quarkus-jdbc-postgresql Datei deklarierten PostgreSQL-Abhängigkeit ), lädt das Docker-Image von PostgreSQL herunter und startet einen Container mit der Datenbank. Anschließend wird automatisch die Todo Tabelle in der Datenbank erstellt.

Stellen Sie sicher, dass Docker lokal auf Ihrem Computer ausgeführt wird, und führen Sie die to-do-Anwendung mithilfe dieses Befehls aus:

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

Die Quarkus-Anwendung sollte starten und eine Verbindung zu Ihrer Datenbank herstellen. Die folgende Ausgabe sollte angezeigt werden:

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>

Zum Testen der Anwendung können Sie cURL verwenden.

Erstellen Sie in einem separaten Terminal ein neues to-do Element in der Datenbank mit dem folgenden Befehl. Sie sollten das Protokoll in der Konsole von Quarkus sehen:

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

Dieser Befehl sollte das erstellte Element (mit einem Bezeichner) zurückgeben:

{"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"}

Erstellen Sie mithilfe des folgenden cURL-Befehls eine zweite 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

Rufen Sie als Nächstes die Daten mithilfe einer neuen cURL-Anforderung ab:

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

Dieser Befehl gibt die Liste der to-do Elemente zurück, einschließlich der von Ihnen erstellten Elemente:

[ 
  {"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}
]

Testen der Anwendung

Zum Testen der Anwendung können Sie die vorhandene TodoResourceTest Klasse verwenden. Er muss den REST-Endpunkt testen. Zum Testen des Endpunkts wird RESTAssuredverwendet. Ersetzen Sie Code in der TodoResourceTest-Klasse durch den folgenden Code:

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);
    }
}

Wenn Sie die Anwendung testen, muss Docker Desktop ausgeführt werden, da Quarkus erkennt, dass die PostgreSQL-Datenbank zum Testen benötigt wird. Testen Sie die Anwendung mithilfe dieses Befehls:

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

Die angezeigte Ausgabe sollte so ähnlich aussehen wie die folgende:

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