The English version of quarkus.io is the official project site. Translated sites are community supported on a best-effort basis.

Creando su primera aplicación

Aprende como crear una aplicación Hello World de Quarkus. Esta guía cubre:

  • Puesta en marcha de una aplicación

  • Creación de un endpoint JAX-RS

  • Inyección de beans

  • Pruebas funcionales

  • Packaging de la aplicación

1. Requisitos previos

To complete this guide, you need:

  • Roughly 15 minutes

  • An IDE

  • JDK 11+ installed with JAVA_HOME configured appropriately

  • Apache Maven 3.8.1+

  • Optionally the Quarkus CLI if you want to use it

Verifique que Maven está usando el Java que espera

If you have multiple JDK’s installed, it is not certain Maven will pick up the expected java and you could end up with unexpected results. You can verify which JDK Maven uses by running mvn --version.

2. Arquitectura

En esta guía, creamos una aplicación sencilla que sirve un endpoint de hello. Para demostrar la inyección de dependencias, este endpoint utiliza un bean greeting.

Arquitectura,

Esta guía también cubre las pruebas del endpoint.

3. Solución

Le recomendamos que siga las instrucciones desde el Proyecto de Bootstrapping y en adelante para crear la aplicación paso a paso.

Sin embargo, puede ir directamente al ejemplo completo.

Descarga un archive o clona el repositorio git:

git clone https://github.com/quarkusio/quarkus-quickstarts.git

La solución se encuentra en getting-started directorio.

4. Puesta en marcha del proyecto

La forma más fácil de crear un nuevo proyecto de Quarkus es abrir un terminal y ejecutar el siguiente comando:

Para usuarios de Linux y MacOS

CLI
quarkus create app org.acme:getting-started \
    --extension=resteasy-reactive
cd getting-started

To create a Gradle project, add the --gradle or --gradle-kotlin-dsl option.

For more information about how to install the Quarkus CLI and use it, please refer to the Quarkus CLI guide.

Maven
mvn io.quarkus.platform:quarkus-maven-plugin:2.13.0.Final:create \
    -DprojectGroupId=org.acme \
    -DprojectArtifactId=getting-started \
    -Dextensions="resteasy-reactive"
cd getting-started

To create a Gradle project, add the -DbuildTool=gradle or -DbuildTool=gradle-kotlin-dsl option.

Para los usuarios de Windows

  • Si utiliza cmd , (no utilice la barra invertida \ y ponga todo en la misma línea)

  • Si utiliza Powershell, envuelva los parámetros de -D entre comillas dobles, por ejemplo "-DprojectArtifactId=getting-started"

Genera lo siguiente en ./getting-started:

  • la estructura de Maven

  • un recurso de org.acme.GreetingResource expuesto en /hello

  • una prueba unitaria asociada

  • una página inicial que es accesible en <a href="http://localhost:8080" class="bare">http://localhost:8080</a>; después de iniciar la aplicación

  • ejemplo Dockerfile archivos para los modos native y jvm en src/main/docker

  • el archivo de configuración de la aplicación

Una vez generado, mira el pom.xml. Encontrarás la importación Quarkus BOM, permitiendo omitir la versión de las diferentes dependencias de Quarkus. Además, se puede ver el quarkus-maven-plugin responsable del empaquetado de la aplicación y también proporcionar el modo de desarrollo.

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>${quarkus.platform.group-id}</groupId>
            <artifactId>quarkus-bom</artifactId>
            <version>${quarkus.platform.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

<build>
    <plugins>
        <plugin>
            <groupId>${quarkus.platform.group-id}</groupId>
            <artifactId>quarkus-maven-plugin</artifactId>
            <version>${quarkus.platform.version}</version>
            <extensions>true</extensions>
            <executions>
                <execution>
                    <goals>
                        <goal>build</goal>
                        <goal>generate-code</goal>
                        <goal>generate-code-tests</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

En un proyecto Gradle, se encontraría una configuración similar:

  • el plugin Quarkus Gradle

  • una directiva enforcedPlatform para Quarkus BOM

Si nos centramos en la sección de dependencias, se puede ver la extensión que permite el desarrollo de aplicaciones REST:

pom.xml
<dependency>
    <groupId>io.quarkus</groupId>
    <artifactId>quarkus-resteasy-reactive</artifactId>
</dependency>
build.gradle
implementation("io.quarkus:quarkus-resteasy-reactive")

4.1. Los recursos JAX-RS

Durante la creación del proyecto, se ha creado el archivo src/main/java/org/acme/GreetingResource.java con el siguiente contenido:

package org.acme;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

@Path("/hello")
public class GreetingResource {

    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public String hello() {
        return "Hello from RESTEasy Reactive";
    }
}

Se trata de un endpoint REST muy sencillo, que devuelve "Hello from RESTEasy Reactive" a las peticiones en "/hello".

Diferencias con el vanilla JAX-RS

Con Quarkus, no es necesario crear una clase Application. Se admite, pero no se requiere. Además, solo se crea una instancia del recurso y no una por solicitud. Esto se puede configurar utilizando las diferentes anotaciones de *Scoped ( ApplicationScoped, RequestScoped, etc).

5. Ejecución de la aplicación

Ahora estamos listos para ejecutar nuestra aplicación:

CLI
quarkus dev
Maven
./mvnw quarkus:dev
Gradle
./gradlew --console=plain quarkusDev
[INFO] --------------------< org.acme:getting-started >---------------------
[INFO] Building getting-started 1.0.0-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ getting-started ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] skip non existing resourceDirectory <path>/getting-started/src/main/resources
[INFO]
[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ getting-started ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 2 source files to <path>/getting-started/target/classes
[INFO]
[INFO] --- quarkus-maven-plugin:<version>:dev (default-cli) @ getting-started ---
Listening for transport dt_socket at address: 5005
2019-02-28 17:05:22,347 INFO  [io.qua.dep.QuarkusAugmentor] (main) Beginning quarkus augmentation
2019-02-28 17:05:22,635 INFO  [io.qua.dep.QuarkusAugmentor] (main) Quarkus augmentation completed in 288ms
2019-02-28 17:05:22,770 INFO  [io.quarkus] (main) Quarkus started in 0.668s. Listening on: http://localhost:8080
2019-02-28 17:05:22,771 INFO  [io.quarkus] (main) Installed features: [cdi, resteasy-reactive]

Una vez iniciado, puede usar el endpoint proporcionado:

$ curl -w "\n" http://localhost:8080/hello
Hello from RESTEasy Reactive

Pulsa CTRL+C para detener la aplicación, o mantenla en funcionamiento y disfruta de la rapidísima recarga en caliente.

Añadir automáticamente una nueva línea con curl -w "\n"

En este ejemplo utilizamos curl -w "\n" para evitar que su terminal imprima un '%' o ponga el resultado y el siguiente comando en la misma línea.

6. Uso de la inyección

La inyección de dependencias en Quarkus se basa en ArC, que es una solución de inyección de dependencias basada en CDI y adaptada a la arquitectura de Quarkus. Si eres nuevo en CDI, te recomendamos que leas la guía de Introducción a CDI.

Quarkus sólo implementa un subconjunto de las características de CDI y viene con características no estándar y APIS específicas, puedes aprender más sobre esto en la Guía de contextos e inyección de dependencias.

ArC viene como una dependencia de quarkus-resteasy-reactive por lo que ya lo tienes a mano.

Vamos a modificar la aplicación y a añadir un bean de acompañamiento. Crea el archivo src/main/java/org/acme/GreetingService.java con el siguiente contenido:

package org.acme;

import javax.enterprise.context.ApplicationScoped;

@ApplicationScoped
public class GreetingService {

    public String greeting(String name) {
        return "hello " + name;
    }

}

Edite la clase GreetingResource para inyectar el GreetingService y cree un nuevo punto final utilizándolo:

package org.acme;

import javax.inject.Inject;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

@Path("/hello")
public class GreetingResource {

    @Inject
    GreetingService service;

    @GET
    @Produces(MediaType.TEXT_PLAIN)
    @Path("/greeting/{name}")
    public String greeting(String name) {
        return service.greeting(name);
    }

    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public String hello() {
        return "hello";
    }
}

Si has detenido la aplicación (ten en cuenta que no tienes que hacerlo, los cambios se desplegarán automáticamente por nuestra función de recarga en vivo), reinicia la aplicación con:

CLI
quarkus dev
Maven
./mvnw quarkus:dev
Gradle
./gradlew --console=plain quarkusDev

A continuación, compruebe que el endpoint devuelve hello quarkus como se esperaba:

$ curl -w "\n" http://localhost:8080/hello/greeting/quarkus
hello quarkus

7. Modo de desarrollo

quarkus:dev ejecuta Quarkus en modo de desarrollo. Esto permite la recarga en vivo con compilación en segundo plano, lo que significa que cuando se modifican los archivos Java y/o los archivos de recursos y se actualiza el navegador, estos cambios tendrán efecto automáticamente. Esto funciona también para los archivos de recursos como el archivo de propiedades de configuración. Al actualizar el navegador, se realiza un análisis del área de trabajo y, si se detecta algún cambio, se recopilaran los archivos Java y se vuelve a desplegar la aplicación; la solicitud se atiende entonces con la aplicación re-desplegada. Si hay algún problema con la compilación o el despliegue, una página de error le informará.

Esto también c un depurador en el puerto 5005. Si quieres esperar a que el depurador se conecte antes de ejecutarlo puedes pasar -Dsuspend en la línea de comandos. Si no quieres el depurador en absoluto puedes usar -Ddebug=false.

8. Probando

De acuerdo, hasta aquí todo bien, pero no sería mejor con unas cuantas pruebas, por si acaso.

En el archivo de construcción generado, puede ver 2 dependencias de prueba:

pom.xml
<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>
build.gradle
testImplementation("io.quarkus:quarkus-junit5")
testImplementation("io.rest-assured:rest-assured")

Quarkus es compatible con las pruebas de JUnit 5.

Debido a esto, en el caso de Maven, se debe establecer la versión del Surefire Maven Plugin, ya que la versión por defecto no soporta JUnit 5:

<plugin>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>${surefire-plugin.version}</version>
    <configuration>
       <systemPropertyVariables>
          <java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager>
          <maven.home>${maven.home}</maven.home>
       </systemPropertyVariables>
    </configuration>
</plugin>

También establecemos la propiedad del sistema java.util.logging para asegurarnos de que las pruebas utilizarán el gestor de registros correcto y maven.home para asegurarnos de que se aplica la configuración personalizada de ${maven.home}/conf/settings.xml (si la hay).

El proyecto generado contiene una prueba sencilla. Edite el src/test/java/org/acme/GreetingResourceTest.java para que coincida con el siguiente contenido:

package org.acme;

import io.quarkus.test.junit.QuarkusTest;
import org.junit.jupiter.api.Test;

import java.util.UUID;

import static io.restassured.RestAssured.given;
import static org.hamcrest.CoreMatchers.is;

@QuarkusTest
public class GreetingResourceTest {

    @Test    (1)
    public void testHelloEndpoint() {
        given()
          .when().get("/hello")
          .then()
             .statusCode(200)    (2)
             .body(is("hello"));
    }

    @Test
    public void testGreetingEndpoint() {
        String uuid = UUID.randomUUID().toString();
        given()
          .pathParam("name", uuid)
          .when().get("/hello/greeting/{name}")
          .then()
            .statusCode(200)
            .body(is("hello " + uuid));
    }

}
1 Utilizando el runner QuarkusTest, se indica a JUnit que inicie la aplicación antes que las pruebas.
2 Compruebe el código de estado de la respuesta HTTP y el contenido

These tests use RestAssured, but feel free to use your favorite library.

Puedes ejecutarlas con Maven:

./mvnw test

También puede ejecutar la prueba desde su IDE directamente (asegúrese de detener la aplicación primero).

Por defecto, las pruebas se ejecutarán en el puerto 8081 para no entrar en conflicto con la aplicación en ejecución. Configuramos automáticamente RestAssured para utilizar este puerto. Si desea utilizar un cliente diferente, deberá utilizar la anotación @TestHTTPResource para inyectar directamente la URL de la aplicación probada en un campo de la clase de prueba. Este campo puede ser del tipo String, URL o URI. A esta anotación también se le puede dar un valor para la ruta de prueba. Por ejemplo, si quiero probar un Servlet mapeado en /myservlet sólo tendría que añadir lo siguiente a mi prueba:

@TestHTTPResource("/myservlet")
URL testUrl;

El puerto de prueba puede ser controlado a través de la propiedad de configuración quarkus.http.test-port. Quarkus también crea una propiedad del sistema llamada test.url que se establece en la URL de prueba base para situaciones en las que no se puede utilizar la inyección.

9. Trabajar con un proyecto multimodal o con módulos externos

Quarkus utiliza en gran medida Jandex en tiempo de construcción, para descubrir varias clases o anotaciones. Una aplicación inmediatamente reconocible de esto, es el descubrimiento de bean CDI. Como resultado, la mayoría de las extensiones de Quarkus no funcionarán correctamente si este descubrimiento en tiempo de construcción no está configurado correctamente.

Este índice se crea por defecto en el proyecto en el que se configura Quarkus, gracias a nuestros plugins de Maven y Gradle.

Sin embargo, cuando trabajes con un proyecto multimódulo, asegúrate de leer la sección Working with multi-module projects de las guías de Maven o Gradle.

Si tiene previsto utilizar módulos externos (por ejemplo, una biblioteca externa para todos sus objetos de dominio), tendrá que dar a conocer estos módulos al proceso de indexación, ya sea añadiendo el plugin de Jandex (si puede modificarlos) o a través de la propiedad quarkus.index-dependency dentro de su application.properties (útil en los casos en que no pueda modificar el módulo).

Asegúrese de leer la sección de Bean Discovery de la guía CDI para obtener más información.

10. Empaquetar y ejecutar la aplicación

La aplicación se empaqueta con:

CLI
quarkus build
Maven
./mvnw install
Gradle
./gradlew build

Produce varias salidas en /target:

  • getting-started-1.0.0-SNAPSHOT.jar - que contiene sólo las clases y recursos de los proyectos, es el artefacto regular producido por la construcción de Maven - no es el jar ejecutable;

  • el directorio quarkus-app que contiene el archivo jar quarkus-run.jar - siendo un jar ejecutable. Tenga en cuenta que no es un über-jar ya que las dependencias se copian en subdirectorios de quarkus-app/lib/.

Puedes ejecutar la aplicación con: java -jar target/quarkus-app/quarkus-run.jar

Si quieres desplegar tu aplicación en algún lugar (normalmente en un contenedor), necesitas desplegar todo el directorio quarkus-app.
Antes de ejecutar la aplicación, no olvides detener el modo de recarga en caliente (pulsa CTRL+C), o tendrás un conflicto de puertos.

By default, when a Quarkus application starts (in regular or dev mode), it will display an ASCII art banner. The banner can be disabled by setting quarkus.banner.enabled=false in application.properties, by setting the -Dquarkus.banner.enabled=false Java System Property, or by setting the QUARKUS_BANNER_ENABLED environment variable to false. Furthermore, users can supply a custom banner by placing the banner file in src/main/resources and configuring quarkus.banner.path=name-of-file in application.properties.

12. ¿Qué es lo que sigue?

Esta guía cubre la creación de una aplicación utilizando Quarkus. Sin embargo, hay mucho más. Recomendamos continuar el viaje con la guía de Guía para construir un ejecutable nativo, donde se aprende a crear un ejecutable nativo y empaquetarlo en un contenedor. Si te interesa lo reactivo, te recomendamos la guía Primeros pasos con la guía reactiva, donde podrás ver cómo implementar aplicaciones reactivas con Quarkus.

Además, el documento Guía de herramientas explica cómo:

  • armar un proyecto en una sola línea de comandos

  • activar el modo de desarrollo (recarga en caliente)

  • importar el proyecto en su IDE favorito

  • y más