Ejercicio: Creación de una aplicación de Quarkus
En esta unidad, creará una aplicación básica de Quarkus. Puede usar Maven para arrancar la aplicación y un entorno de desarrollo integrado (IDE) de su elección para editar el código. Utilice el terminal de su elección para ejecutar el código. Use Docker para iniciar una base de datos de PostgreSQL local para poder ejecutar y probar la aplicación localmente.
Generación de la aplicación Quarkus mediante Maven
Hay varias maneras de generar una estructura de proyecto de Quarkus. Puede usar la interfaz web de Quarkus, un complemento IDE o el complemento Quarkus Maven. Vamos a usar el complemento Maven para generar la estructura del proyecto.
La aplicación se genera con varias dependencias:
- La dependencia
resteasypara exponer un punto de conexión REST - Dependencia de
jacksonpara serializar y deserializar JSON - La dependencia
hibernatepara interactuar con la base de datos - La dependencia de
postgresqlpara conectarse a la base de datos PostgreSQL - Dependencia de
dockerpara construir una imagen de Docker
No es necesario especificar las dependencias de Azure porque ejecuta la aplicación localmente primero y, a continuación, implementa una versión en contenedor de ella en Azure Container Apps.
En un símbolo del sistema, genere la aplicación to-do:
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"
Este comando crea un nuevo proyecto de Quarkus. Genera una estructura de directorios de Maven (src/main/java para el código fuente y src/test/java para las pruebas). Crea algunas clases de Java, algunas pruebas y algunos Dockerfiles. También genera un archivo pom.xml con todas las dependencias necesarias (Hibernate, RESTEasy, Jackson, PostgreSQL y 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>
Nota:
Todas las dependencias del archivo pom.xml se definen en el BOM (lista de materiales) de Quarkus io.quarkus.platform:quarkus-bom.
Programar la aplicación
A continuación, cambie el nombre de la clase MyEntity.java generada a Todo.java (ubicado en la misma carpeta que el archivo TodoResource.java). Reemplace el código existente por el código Java siguiente. Usa la API de Persistencia de Java (jakarta.persistence.* paquete) para almacenar y recuperar datos del servidor PostgreSQL. También usa Hibernate ORM con Panache (heredando de io.quarkus.hibernate.orm.panache.PanacheEntity) para simplificar la capa de persistencia.
Use una entidad JPA (@Entity) para asignar el objeto Todo java directamente a la tabla de Todo postgreSQL. Después, el punto de conexión REST de TodoResource crea una nueva clase de entidad Todo y la persiste. Esta clase es un modelo de dominio que está mapeado en la tabla Todo. JPA crea automáticamente la tabla.
Al extender PanacheEntity se obtiene una serie de métodos genéricos de creación, lectura, actualización y eliminación (CRUD) para el tipo. Por lo tanto, puede hacer cosas como guardar y eliminar objetos Todo en una sola línea de código Java.
Agregue el código siguiente a la entidad 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 +
'}';
}
}
Para administrar esa clase, actualice el TodoResource para que pueda publicar interfaces REST para almacenar y recuperar datos mediante HTTP. Abra la clase TodoResource y reemplace el código por lo siguiente:
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();
}
}
Ejecución de la aplicación
Al ejecutar la aplicación en modo de desarrollo, Docker debe ejecutarse. Esto se debe a que Quarkus detecta que necesita una base de datos postgreSQL (debido a la dependencia de PostgreSQL quarkus-jdbc-postgresql declarada en el archivo pom.xml), descarga la imagen de Docker de PostgreSQL e inicia un contenedor con la base de datos. A continuación, crea automáticamente la tabla Todo en la base de datos.
Asegúrese de que Docker se ejecuta localmente en la máquina y ejecute la aplicación to-do mediante este comando:
cd todo
./mvnw quarkus:dev # On Mac or Linux
mvnw.cmd quarkus:dev # On Windows
La aplicación Quarkus debe iniciarse y conectarse a la base de datos. Deberías ver la siguiente salida:
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>
Puede usar cURL para probar la aplicación.
En un terminal independiente, cree una nueva tarea en la base de datos con el siguiente comando. Debería ver el registro en la consola de 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
Este comando debe devolver el elemento creado (con un identificador):
{"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"}
Cree una segunda tarea mediante el siguiente comando cURL:
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
A continuación, recupere los datos mediante una nueva solicitud cURL:
curl http://127.0.0.1:8080/api/todos
Este comando muestra la lista de tareas, incluidas las que ha creado:
[
{"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}
]
Prueba de la aplicación
Para probar la aplicación, puede usar la clase TodoResourceTest existente. Necesita probar el punto de conexión REST. Para probar el punto de conexión, usa RESTAssured. Reemplace el código de la clase TodoResourceTest por el código siguiente:
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);
}
}
Al probar la aplicación, Docker Desktop debe ejecutarse porque Quarkus detecta que necesita la base de datos PostgreSQL para realizar pruebas. Pruebe la aplicación mediante este comando:
./mvnw clean test # On Mac or Linux
mvnw.cmd clean test # On Windows
Debería ver una salida parecida a esta:
[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] ------------------------------------------------------------------------