Exercice - Créer une application Quarkus
Dans cette unité, vous créez une application Quarkus de base. Vous utilisez Maven pour démarrer l’application, et l’environnement de développement intégré (IDE) de votre choix pour modifier le code. Utilisez un terminal de votre choix pour exécuter le code. Vous utilisez Docker pour démarrer une base de données PostgreSQL locale afin de pouvoir exécuter et tester l’application localement.
Générer l’application Quarkus avec Maven
Vous pouvez générer une structure de projet Quarkus de plusieurs façons. Vous pouvez utiliser l’interface web Quarkus, un plug-in d’IDE ou le plug-in Quarkus Maven. Utilisons le plug-in Maven pour générer la structure du projet.
Vous générez votre application avec plusieurs dépendances :
- La dépendance
resteasy
pour exposer un point de terminaison REST - La dépendance
jackson
pour sérialiser et désérialiser le code JSON - La dépendance
hibernate
pour interagir avec la base de données - La dépendance
postgresql
pour se connecter à la base de données PostgreSQL - La dépendance
docker
pour créer une image Docker
Vous n’avez pas besoin de spécifier les dépendances Azure, car vous exécutez d’abord votre application localement, puis en déployez une version conteneurisée sur Azure Container Apps.
À l’invite de commandes, générez l’application de tâches :
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"
Cette commande crée un projet Quarkus. Elle génère une structure de répertoires Maven (src/main/java
pour le code source et src/test/java
pour les tests). Elle crée des classes Java, des tests et des Dockerfiles. Elle génère également un fichier pom.xml avec toutes les dépendances nécessaires (Hibernate, RESTEasy, Jackson, PostgreSQL et 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>
Remarque
Toutes les dépendances dans le fichier pom.xml sont définies dans la nomenclature Quarkus io.quarkus.platform:quarkus-bom
.
Coder l’application
Ensuite, renommez la classe MyEntity.java générée en Todo.java (située dans le même dossier que le fichier TodoResource.java). Remplacez le code existant par le code Java suivant. Elle utilise l’API de persistance Java (package jakarta.persistence.*
) pour stocker et récupérer les données de votre serveur PostgreSQL. Elle utilise également Hibernate ORM avec Panache (héritage de io.quarkus.hibernate.orm.panache.PanacheEntity
) pour simplifier la couche de persistance.
Vous utilisez une entité JPA (@Entity
) pour mapper directement l’objet Java Todo
à la table Todo
PostgreSQL. Le point de terminaison REST TodoResource
crée ensuite une classe d’entité Todo
et la rend persistante. Cette classe est un modèle de domaine qui est mappé à la table Todo
. Le tableau est créé automatiquement par JPA.
L’extension de PanacheEntity
vous permet d’obtenir un certain nombre de méthodes de création, de lecture, de mise à jour et de suppression (CRUD) génériques pour votre type. Vous pouvez donc effectuer des opérations comme l’enregistrement et la suppression d’objets Todo
dans une seule ligne de code Java.
Ajoutez le code suivant à l’entité 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 +
'}';
}
}
Pour gérer cette classe, mettez à jour la classe TodoResource
pour publier des interfaces REST afin de stocker et récupérer des données en utilisant HTTP. Ouvrez la classe TodoResource
et remplacez le code par le suivant :
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();
}
}
Exécution de l'application
Lorsque vous exécutez l’application en mode développement, Docker doit être en cours d’exécution. En effet, Quarkus détecte que vous avez besoin d’une base de données PostgreSQL (en raison de la dépendance PostgreSQL quarkus-jdbc-postgresql
déclarée dans le fichier pom.xml), télécharge l’image Docker PostgreSQL et démarre un conteneur avec la base de données. Il crée ensuite automatiquement la table Todo
dans la base de données.
Vérifiez que Docker s’exécute localement sur votre machine et exécutez l’application de tâches avec cette commande :
cd todo
./mvnw quarkus:dev # On Mac or Linux
mvnw.cmd quarkus:dev # On Windows
L’application Quarkus démarre et se connecte à votre base de données. Vous devez normalement voir la sortie suivante :
[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>
Pour tester l’application, vous pouvez utiliser cURL.
Dans un terminal distinct, créez un élément de tâche dans la base de données avec la commande suivante. Vous devez voir le journal dans la console 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
Cette commande doit retourner l’élément créé (avec un identificateur) :
{"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"}
Créez une deuxième tâche en utilisant la commande cURL suivante :
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
Ensuite, récupérez les données à l’aide d’une nouvelle requête cURL :
curl http://127.0.0.1:8080/api/todos
Cette commande renvoie la liste des éléments de tâche, y compris les éléments que vous avez créés :
[
{"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}
]
Test de l’application
Pour tester l’application, vous pouvez utiliser la classe existante TodoResourceTest
. Il doit tester le point de terminaison REST. Pour tester le point de terminaison, il utilise RESTAssured. Remplacez le code dans la classe TodoResourceTest
par le code suivant :
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);
}
}
Lorsque vous testez l’application, Docker Desktop doit être en cours d’exécution parce que Quarkus détecte qu’il a besoin de la base de données PostgreSQL pour les tests. Testez l’application en utilisant cette commande :
./mvnw clean test # On Mac or Linux
mvnw.cmd clean test # On Windows
La sortie doit ressembler à ceci :
[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] ------------------------------------------------------------------------