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:
- Dependencia de
resteasy
para exponer un punto de conexión REST - Dependencia de
jackson
para serializar y deserializar JSON - Dependencia de
hibernate
para interactuar con la base de datos - Dependencia de
postgresql
para conectarse a la base de datos postgreSQL - Dependencia de
docker
para compilar 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 la lista de materiales de Quarkus (lista de materiales) io.quarkus.platform:quarkus-bom
.
Incorporación del código de 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 (heredar 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. A continuación, el punto de conexión rest de TodoResource
crea una nueva clase de entidad Todo
y la conserva. Esta clase es un modelo de dominio que se asigna a 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 un nuevo elemento de to-do en la base de datos con el comando siguiente. 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 un segundo to-do 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 devuelve la lista de elementos de to-do, incluidos los elementos que creó:
[
{"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. Debe 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 la salida similar a la siguiente:
[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] ------------------------------------------------------------------------