Spring Boot con Kotlin

Fusiona un lenguaje con un framework enfocados a la velocidad y simplicidad

En el mundillo del desarrollo web en Java está de más hablar de Spring Framework. A lo largo de los años Spring ha estado un paso adelante en cuanto a desarrollo web, cloud, microservicios y backend en general se refiere y para los desarrolladores se ha convertido en el estándar de facto por su potencia, simplicidad y capacidad de integración con otros sistemas.

En su momento Spring nació debido a las limitaciones de JavaEE y la verbosidad con la que se escribían cualquier tipo de aplicaciones con Java. Para resolver esta problemática Spring desarrolló un astuto sistema de anotaciones en base al patrón de la Inyección de Dependencias y la Inversión de Control.

A pesar de todas las facilidades que nos brinda Spring a los desarrolladores siempre nos ha quedado el regustillo amargo de que aún con Spring, el código escrito seguía siendo verboso y algo feo debido a que es algo inherente al lenguaje Java.

En el último año hemos visto cómo ha salido a la luz Kotlin, un lenguaje que ha creado Jetbrains con el objetivo de simplificar y suplir las carencias de Java. Kotlin corre sobre la Máquina Virtual de Java y se destaca por su interoperabilidad, es decir, no es necesario para usar Kotlin crear un proyecto desde cero, todas las clases Java se pueden usar en Kotlin y viceversa.

Kotlin ha sido acogido con fuerza por la comunidad, sobretodo por la comunidad de desarrolladores Android, con tal fuerza que ya Google anunció esta primavera que Kotlin se convertía en el segundo lenguaje oficial para desarrollar en Android, pero Kotlin es eficiente no solamente en Android. Vamos a ver como usarlo con Spring.


Spring 5 "La revolución web"

Con la versión 5 de Spring han cambiado muchas cosas y una de las más importantes es que se le da soporte oficial a Kotlin (podéis ver más detalles aquí).

Una de las mejores cosas que podemos hacer es extender el framework a nuestra medida, gracias a las funciones de extensión de Kotlin. Esto lo ha realizado Spring internamente para mejorar algunas clases y darles más potencia, por ejemplo la clase Model ha sido extendida en ModelExtensions.kt y podremos hacer cosas así:


model["blogName"] = "Un Blog Decode"

También Spring ha aprovechado internamente la mejora de los genéricos en Kotlin para extender las clases RestTemplate y el nuevo WebClient para realizar llamadas de este tipo con el nuevo API Flux:

//lo que había que hacer en Java
Flux<User> users  = client.get().retrieve().bodyToFlux(User.class)

//como lo haríamos en Kotlin con los genéricos
val users = client.get().retrieve().bodyToFlux<User>()

En Spring Initializr también ya podemos escoger Kotlin y automáticamente nos configurará nuestro proyecto Spring Boot con este lenguaje.

Si nos fijamos en el fichero build.gradle que nos genera nos podemos dar cuenta de dos particularidades. Una que para configurar Kotlin es tan sencillo como añadir al classpath par de dependencias, y también otra cosa interesantes es que los plugins que "aplica" destaca uno llamado kotlin-spring, el cual es un plugin creado por la gente de Jetbrains para mejorar el soporte de Spring en su lenguaje.


buildscript {
	ext {
		kotlinVersion = '1.1.3-2'
		springBootVersion = '1.5.6.RELEASE'
	}
	repositories {
		mavenCentral()
	}
	dependencies {
		classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
		classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:${kotlinVersion}")
		classpath("org.jetbrains.kotlin:kotlin-allopen:${kotlinVersion}")
	}
}

apply plugin: 'kotlin'
apply plugin: 'kotlin-spring'
apply plugin: 'eclipse'
apply plugin: 'org.springframework.boot'

version = '0.0.1-SNAPSHOT'
sourceCompatibility = 1.8
compileKotlin {
	kotlinOptions.jvmTarget = "1.8"
}
compileTestKotlin {
	kotlinOptions.jvmTarget = "1.8"
}

repositories {
	mavenCentral()
}


dependencies {
	compile('org.springframework.boot:spring-boot-starter-data-jpa')
	compile('org.springframework.boot:spring-boot-starter-data-rest')
	compile('org.springframework.boot:spring-boot-starter-freemarker')
	compile('org.springframework.boot:spring-boot-starter-security')
	compile('org.springframework.boot:spring-boot-starter-web')
	compile("org.jetbrains.kotlin:kotlin-stdlib-jre8:${kotlinVersion}")
	compile("org.jetbrains.kotlin:kotlin-reflect:${kotlinVersion}")
	testCompile('org.springframework.boot:spring-boot-starter-test')
	testCompile('org.springframework.security:spring-security-test')
}

Pasándonos a Kotlin

Como véis, es bastante sencillo configurar un proyecto aunando estas dos tecnologías. Para facilitar esta tarea yo he migrado a Kotlin algunas de las guías de Spring (https://spring.io/guides) que están en Java y las he subido al siguiente repositorio de Github:

https://github.com/atrujillofalcon/spring-guides-kotlin

Poco a poco iré subiendo más de los ejemplo pero os animo a contribuir vosotros y subir o mejorar lo que ya está migrado.

Para importar el proyecto simplemente tenéis que abrirlo con vuestro IDE favorito, por supuesto recomiendo IntelliJ IDEA (si no tenéis la versión de pago podéis usar la Community), y ya se os descargarán todas las dependencias. He creado el proyecto como un "Gradle Multiproject" para así compartir la configuración común padre en cada uno de los submódulos. Vamos a desglosar rápidamente uno de los ejemplos para ver como se simplifica el desarrollo con Kotlin.


Creando un Servicio Rest con Kotlin y Spring

Después de habernos importado el proyecto veremos que uno de los módulos es el gs-rest-service. Aquí construiremos un servicio web sencillito pero en el que veremos ya con que facilidad podemos desarrollar en Kotlin y la cantidad de líneas que nos ahorramos.

Vamos a ver la clase de entrada de Spring Boot Application.kt

Lo más peculiar que podemos comentar aquí es que en Kotlin no existe el concepto de variables ni métodos estáticos. Para esto existe la palabra clave companion object que internamente crea como una especie de objeto Singleton. Con la anotación @JvmStatic le indicamos al compilador que el método main debe ser  static en el bytecode generado; esto solamente lo tendremos que realizar en ocasiones puntuales como el método main de Java.

La siguiente clase que veremos es el modelo Greeeting:


data class Greeting(val id: Long, val content: String)

Podéis daros cuenta de la facilidad con la que definimos un POJO (¡en una sola línea!). Con solo poner el prefijo data a la clase, ya Kotlin nos crea el constructor,getter's,setter's, y métodos equals() y toString().

Y por último veremos el controlador GreetingController:


@RestController
class GreetingController {
    companion object {
        val counter = AtomicLong()
    }

    @RequestMapping("/greeting")
    fun greeting(@RequestParam(value = "name", defaultValue = "World") name: String): Greeting =
            Greeting(counter.incrementAndGet(), "Hello, $name!")
}

Lo más interesante a reseñar es que como véis podéis definir valores por defecto al parámetro de entrada name. También podemos ver que cuando el cuerpo de las funciones se puede declarar en una sola línea no hace falta poner las llaves ni el return, simplemente con el símbolo igual y lo que devuelve nos basta. En este caso estamos devolviendo una nueva instancia de la clase Greeting y como os daréis cuenta no es necesario la palabra clave new de Java para instanciar una clase. Otra cosa que me gusta bastante es la capacidad de añadir variables a los string's como si fueran plantillas con el símbolo de dólar + "nombre de la variable".

Pues nada, solamente nos queda arrancar la aplicación Spring Boot y veremos como se ejecuta perfectamente en nuestro local.

Espero que con este post os animéis a empezar a desarrollar vuestras aplicaciones web con Kotlin y Spring, sin duda una excelente dupla. Happy Decoding!

Más entradas de blog

Curso Intensivo Liferay 7 Digital Experience I

Hola! Aquí comienza una serie de tutoriales en los cuales aprenderemos todos los conceptos...

Patrón Step Builder

Hola a todos ¡cuanto tiempo sin vernos! Estos últimos meses he estado con mucho trabajo y no...

Añadir comentarios