Crear una aplicación con Micronaut + Kotlin + Maven + JDK 17, con el parent de Arquimedes

0
1216

Índice de contenidos

    1. Entorno
    2. Introducción
    3. Instalación Micronaut
    4. JDK 17
    5. Archimedes como parent
    6. Ejemplo
    7. Conclusión

    1. Entorno

    • Hardware: Portátil MacBook Pro 15 pulgadas (2,5 GHz Intel Core i7, 16GB RAM)
    • Sistema Operativo: MacOS Monterey 12.1
    • SDKMAN!
    • Micronaut 3.1.0
    • JDK 17

    2. Introducción

    Micronaut es un framework que permite de una forma sencilla y rápida implementar y testear aplicaciones basadas en microservicios. Nació con el objetivo de superar las limitaciones de otros frameworks disminuyendo el tiempo de arranque y el consumo de memoria gracias a la inyección de dependencias en tiempo de compilación en vez de en ejecución.

    En este tutorial vamos a demostrar lo sencillo que es crear una aplicación con Micronaut usando Maven + Kotlin ejecutándolo con JVM 17, contando con la ayuda del parent de Archimedes creado por Autentia.

    3. Instalación Micronaut

    La manera más recomendada para crear una nueva aplicación de Micronaut es usar Micronaut CLI, para ello es necesario tener instalado Micronaut.

    Nosotros lo haremos mediante SKDMAN! que nos instala todas las dependencias de Micronaut incluyendo su CLI:

    sdk install micronaut

    Si no sabes que es SdkMan recomiendo echar un vistazo al tutorial de Adictos sobre Gestionar tus herramientas de desarrollo con SdkMan

    Cabe destacar que Micronaut dispone de una página para generar un proyecto sin necesidad de Micronaut CLI: Micronaut Launch.

    Para crear un proyecto con Micronaut hay que ejecutar el comando mvn create-app con las especificaciones que necesitemos en cada caso.

    En nuestro caso como queremos desarrollar una aplicación con Maven, Kotlin y JDK 17, el comando que debemos escribir es el siguiente:

    mn create-app micronaut-api-rest-kotlin --build=maven --lang=kotlin --jdk=17

    Es necesario indicar con build que la gestión de dependencias es con Maven porque defecto es Gradle. De la misma manera hay que indicar el lenguaje Kotlin que por defecto sería Java.

    Ya tendríamos nuestro proyecto creado dentro del directorio que hemos indicado: micronaut-api-rest-kotlin

    4. JDK 17

    Para usar Java 17 hay que ternerla instalada localmente. Si no tenemos el JDK 17 instalado podemos hacerlo con el siguiente comando:

    sdk install java 17.0.2-tem

    Si al ejecutar el comando de creación del proyecto hemos indicado la versión que queremos usar se nos configurará en el pom al crearlo, si no es el caso, simplemente tenemos que asegurarnos que en las propiedades del pom aparece el JDK deseado.

    <properties>
      <packaging>jar</packaging>
      <jdk.version>17</jdk.version>
      <release.version>17</release.version>
      <exec.mainClass>micronaut.api.rest.kotlin.ApplicationKt</exec.mainClass>
    </properties>

    5. Archimedes como parent

    En este tutorial hemos decidido utilizar el parent de Maven de Archimedes, biblioteca creada por Autentia que nos facilitará con las propiedades y dependencias de nuestra aplicación.

    Para más información sobre Arquimedes se puede consultar en su web oficial o directamente en su github donde existen varios proyectos con ejemplos.

    Por lo tanto, modificamos el pom cambiando el parent que aparece al crear el proyecto Micronaut, por el de Arquimedes para Micronaut y Kotlin con la última versión disponible en este momento:

    <parent> 
      <groupId>io.archimedesfw.maven.micronaut</groupId> 
      <artifactId>micronaut-kotlin-parent</artifactId> 
      <version>3.3.3</version> 
    </parent>

    Esta última versión de Arquimedes ya cuenta con la configuración de las propiedades referentes a la versión de Kotlin y JDK 17, por lo tanto, no es necesario especificar las propiedades indicadas en el apartado anterior.

    Algo similar ocurre con las dependencias y plugins que no tendremos que preocuparnos de las versiones, ya que estarán establecidas en el parent, sino únicamente de declarar las dependencias que vamos a necesitar. Las dependencias serás las mínimas necesarias y únicamente incluiremos tres plugins: uno para activar los test de integración, otro que nos permite arrancar la aplicación con Maven desde la línea de comandos y otro que nos permite ejecutar y empaquetar nuestra aplicación en un jar por ejemplo

    Nuestro pom tendrá un aspecto similar a esto:

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
      <modelVersion>4.0.0</modelVersion>
      <groupId>micronaut.api.rest.kotlin</groupId>
      <artifactId>micronaut-api-rest-kotlin</artifactId>
      <version>0.1</version>
      <packaging>${packaging}</packaging>
    
      <parent>
        <groupId>io.archimedesfw.maven.micronaut</groupId>
        <artifactId>micronaut-kotlin-parent</artifactId>
        <version>3.3.3</version>
      </parent>
    
      <properties>
        <packaging>jar</packaging>
        <exec.mainClass>micronaut.api.rest.kotlin.ApplicationKt</exec.mainClass>
      </properties>
    
      <dependencies>
        <dependency>
          <groupId>io.micronaut</groupId>
          <artifactId>micronaut-runtime</artifactId>
        </dependency>
        <dependency>
          <groupId>io.micronaut</groupId>
          <artifactId>micronaut-validation</artifactId>
        </dependency>
    
        <!-- Logging system is already integrated with Micronaut so only need to add the dependency to use it -->
        <dependency>
          <groupId>ch.qos.logback</groupId>
          <artifactId>logback-classic</artifactId>
          <scope>runtime</scope>
        </dependency>
    
        <!-- Dependencies for testing with Junit 5 -->
        <dependency>
          <groupId>org.junit.jupiter</groupId>
          <artifactId>junit-jupiter-engine</artifactId>
          <scope>test</scope>
        </dependency>
        <dependency>
          <groupId>io.micronaut.test</groupId>
          <artifactId>micronaut-test-junit5</artifactId>
          <scope>test</scope>
        </dependency>
        <dependency>
          <groupId>io.micronaut</groupId>
          <artifactId>micronaut-http-server-netty</artifactId>
        </dependency>
        <dependency>
          <groupId>io.micronaut</groupId>
          <artifactId>micronaut-http-client</artifactId>
          <scope>compile</scope>
        </dependency>
      </dependencies>
    
      <build>
        <plugins>
          <plugin>
            <!-- Activate integration tests -->
            <!-- This plugin is preconfigured in micronaut-base-parent so you only need to declare it -->
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-failsafe-plugin</artifactId>
          </plugin>
          <plugin>
            <!-- Activate the ability to run module from Maven in the command lines with: -->
            <!--     mvn exec:exec -->
            <!-- This plugin is preconfigured in micronaut-java-parent so you only need to declare it -->
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>exec-maven-plugin</artifactId>
          </plugin>
          <plugin>
            <groupId>io.micronaut.build</groupId>
            <artifactId>micronaut-maven-plugin</artifactId>
          </plugin>
        </plugins>
      </build>
    
    </project>

    6. Ejemplo

    A continuación se va a implementar un pequeño ejemplo para comprobar que compila y se ejecuta nuestra aplicación correctamente.

    Tenemos una clase Welcome con dos atributos:

    package micronaut.api.rest.kotlin
    
    data class Welcome (val greeting: String = "Hello", val name: String = "World")

    Y creamos un controlador con una petición get que nos devolverá el objeto Welcome:

    package micronaut.api.rest.kotlin
    
    import io.micronaut.http.annotation.Controller
    import io.micronaut.http.annotation.Get
    
    @Controller("/hello")
    class HelloController {
    
        @Get
        fun index(): Welcome {
            return Welcome()
        }
    }

    Para probar este controlador implementamos un test de integración:

    package micronaut.api.rest.kotlin
    
    import io.micronaut.http.HttpRequest
    import io.micronaut.http.client.HttpClient
    import io.micronaut.http.client.annotation.Client
    import io.micronaut.test.extensions.junit5.annotation.MicronautTest
    import jakarta.inject.Inject
    import org.junit.jupiter.api.Assertions.assertEquals
    import org.junit.jupiter.api.Test
    
    
    @MicronautTest
    class HelloControllerTestIT {
    
        @Inject
        @field:Client("/")
        lateinit var client : HttpClient
    
        @Test
        fun `should return welcome object equals Hello World`(){
            val request: HttpRequest<Any> = HttpRequest.GET("/hello")
            val result = client.toBlocking().retrieve(request, Welcome::class.java)
    
            assertEquals(Welcome(), result)
        }
    }

    Si arrancamos nuestra aplicación ya sea por la línea de comandos con mvn exec:exec o a través del propio IDE y hacemos una llamada a http://localhost:8080/hello recibiremos como respuesta:

    {"greeting":"Hello","name":"World"}

    Como hemos configurado el plugin de micronaut-maven-plugin al hacer un mvn clean install nos empaquetó nuestra aplicación en un fat jar y podríamos ejecutar el siguiente comando para ejecutar también nuestra aplicación:

    java -jar ./target/micronaut-api-rest-kotlin-0.1.jar

    Código completo en GitHub: micronaut-api-rest-kotlin

    7. Conclusión

    Micronaut es un framework que está cogiendo mucha fuerza y como hemos podido comprobar es muy sencillo crear una aplicación desde cero con este framework independientemente del lenguaje, gestión de dependencias o versión de Java que queramos utilizar. En este tutorial se ha implementado un caso muy sencillo, pero Micronaut ofrece muchas más opciones y características orientadas a los microservicios.

DEJA UNA RESPUESTA

Por favor ingrese su comentario!

He leído y acepto la política de privacidad

Por favor ingrese su nombre aquí

Información básica acerca de la protección de datos

  • Responsable:
  • Finalidad:
  • Legitimación:
  • Destinatarios:
  • Derechos:
  • Más información: Puedes ampliar información acerca de la protección de datos en el siguiente enlace:política de privacidad