Este artigo é o primeiro de uma série que pretende abordar como fazer um backend em Kotlin. Hoje, a ideia é apresentar o Kotlin com um programa simples e mostrar como configurar um ambiente inicial de desenvolvimento.
O que é Kotlin?
Kotlin é uma linguagem de programação criada pela JetBrains, que roda em cima da JVM, concisa, segura, pragmática e focada em interoperabilidade. Pode ser uma alternativa ao Java, uma vez que sua capacidade Funcional e Orientada a Objetos inova nas possibilidades de criação.
Por que Kotlin?
Porque é muito mais gostoso “codar” com ela (sim, estou realmente curtindo bons momentos estudando).
- Open Source;
- 100% interoperável com Java, gerando bytecode da JVM;
- Pode ser utilizada em conjunto com diversos frameworks e bibliotecas disponíveis;
- Menos código;
- Null Safety;
- Funcional e Orientada a Objetos;
- Pode ser utilizada no desenvolvimento de apps Android.
Como começar?
Primeiro, é preciso baixar e instalar o Intellij IDEA neste site. É preciso também ter uma JDK instalada e configurada.
Com o Intellij IDEA instalado e iniciado, vá em Preferences (OSX) ou Settings (Windows/Linux) -> Plugins -> Browse Repositories e escreva Kotlin. Clique em Install. Pronto, agora que está tudo instalado é hora de “codar”!
Criando seu primeiro programa com Kotlin
Clique em File -> New -> Project, selecione Kotlin(JVM) e clique em Next:
O meu Project Name será OlaKotlin. Escolha o seu e clique em Finish:
Criei o pacote ola.kotlin. Você pode escolher o que quiser!
Clique com o botão direito no pacote recém-criado e crie um novo arquivo Kotlin:
Dei o nome de Ola (por falta de criatividade mesmo kkk).
Primeira função Kotlin
Por que não começar com o famoso Hello World simples e básico? Em Java escrevemos este código em um método main, mas no Kotlin escreveremos este código no fun main.
Abra o arquivo Ola.kt (no meu caso) e escreva o seguinte código:
package ola.kotlin /** * Created by Kleber on 30/05/2016. */ fun main(args: Array<String>) { val stringKotlin = "Kotlin" println("Olá $stringKotlin") }
Clique com o botão direito e execute.
Veja o resultado no console: Olá, Kotlin!
Note algumas coisas interessantes neste programa: menos código, variável sem definir qual o tipo, println menos verboso e interpolação de strings com strings templates ($). Simples, não?!
Agora vamos criar algo um pouco mais complexo usando o SpringBoot para levantar um serviço REST simples em Jersey.
Início
Vamos utilizar o Gradle para fazer build e gerenciar as dependências do SpringBoot no projeto. Para isso, crie uma pasta, execute o gradle e importe no IntelliJ. Criei a pasta ServicoKotlin, mas fique à vontade para escolher a sua.
gradle init –type java-library
Ele vai criar a seguinte estrutura:
Com o projeto importado no IntelliJ IDEA, vamos configurar o Gradle para resolver dependências, plugins e o build de nosso projeto.
Abra o arquivo build.gradle, que se encontra na raiz do projeto, e substitua pelo o seguinte conteúdo:
buildscript { // Neste bloco declare variaveis das versoes das principais dependencias e plugins ext { kotlinVersion = '1.0.3' springBootVersion = '1.4.0.RELEASE' jacksonModuleKotlinVersion = '2.7.5' } // Neste bloco declare onde encontrar dependencias para os plugins repositories { //mavenLocal() mavenCentral() //jcenter() } // Neste bloco declare as dependencias dos plugins dependencies { classpath("org.springframework.boot:spring-boot-gradle-plugin:$springBootVersion") classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion") } } // Aplique os plugins abaixo para o suporte do Gradle apply plugin: 'idea' apply plugin: 'java' apply plugin: 'kotlin' apply plugin: 'spring-boot' // Neste bloco declare onde encontrar dependencias para o projeto repositories { // Use 'jcenter' para resolver dependencias do projeto // Podem ser declarados repositorios Maven/Ivy/file jcenter() //mavenLocal() //mavenCentral() } // Neste bloco declare suas dependecias dependencies { compile("org.jetbrains.kotlin:kotlin-stdlib:$kotlinVersion") compile("org.jetbrains.kotlin:kotlin-runtime:$kotlinVersion") compile("org.jetbrains.kotlin:kotlin-reflect:$kotlinVersion") compile("org.springframework.boot:spring-boot-starter:$springBootVersion") compile("org.springframework.boot:spring-boot-starter-web:$springBootVersion") compile("org.springframework.boot:spring-boot-starter-jersey:$springBootVersion") compile("org.springframework.boot:spring-boot-starter-undertow:$springBootVersion") compile("com.fasterxml.jackson.module:jackson-module-kotlin:$jacksonModuleKotlinVersion") testCompile("org.jetbrains.kotlin:kotlin-test:$kotlinVersion") testCompile("org.jetbrains.kotlin:kotlin-test-junit:$kotlinVersion") testCompile("org.springframework.boot:spring-boot-starter-test:$springBootVersion") } // Neste bloco declare o nome e versao do arquivo .jar jar { baseName = 'ServicoKotlin' version = '1.0.0-SNAPSHOT' } // Neste bloco declare onde ficarao os sources e testes sourceSets { main { kotlin { srcDirs 'src/main/kotlin' } } test { kotlin { srcDirs 'src/test/kotlin' } } }
Criando nossas classes
Clique com o botão direito nas pastas java em main.java e test.java e as delete. Também com o botão direito, clique na pasta main, crie o diretório kotlin e marque este como Sources Root. A estrutura deve ficar assim: src/main/kotlin, igual ao que está no sourceSets do script build.gradle.
Crie um pacote à sua escolha (o meu é org.kotlin) e crie um arquivo kotlin dentro com o nome de App. A extensão dos arquivos kotlin é .kt. Neste arquivo vamos criar nossa classe e a função main para o SpringBoot.
package org.kotlin import com.fasterxml.jackson.module.kotlin.KotlinModule import org.springframework.boot.SpringApplication import org.springframework.boot.autoconfigure.SpringBootApplication import org.springframework.context.annotation.Bean import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder import org.springframework.web.client.RestTemplate /** * Created by Kleber on 04/08/2016. */ @SpringBootApplication open class App { @Bean open fun restTemplate(): RestTemplate { val restTemplate = RestTemplate() return restTemplate } @Bean open fun objectMapperBuilder(): Jackson2ObjectMapperBuilder = Jackson2ObjectMapperBuilder().modulesToInstall(KotlinModule()) } fun main(args: Array<String>) { SpringApplication.run(App::class.java, *args) }
Vamos, agora, detalhar este trecho:
@SpringBootApplication é uma anotação de conveniência, que marca a classe com as seguintes anotações com seus atributos default:
- @Configuration: anota a classe como uma fonte de definições de beans para o contexto da aplicação;
- @EnableAutoConfiguration: diz ao SpringBoot para começar a adicionar beans com base nas configurações de classpath e várias configurações de propriedade;
- @ComponentScan: diz ao Spring para procurar outros componentes, configurações e serviços no pacote atual.
Modificador open na classe é o oposto do final do Java. Em Kotlin, todas as classes e métodos são final por padrão, e para o Spring elas não podem ser final devido ao uso de proxy CGLIB.
Uma função restTemplate com anotação @Bean cria uma instância do RestTemplate como um Bean do Spring.
Uma função objectMapperBuilder sem corpo (sim, em Kotlin isto é possível) tem anotação @Bean para registrá-lo no Jackson ObjectMapper.
Em Java, o método main( ) de um aplicativo é convencionalmente definido dentro da classe de aplicação anotada. Isso ocorre porque Java não suporta métodos de nível superior. Em Kotlin, no entanto, nós temos funções top-level. Assim, podemos tornar o principal ponto de entrada do SpringBoot muito mais simples. Com isto, a função main() é definida em uma classe chamada AppKt e não em uma classe App.
A função main() utiliza o método SpringApplication.run() do SpringBoot para iniciar um aplicativo.
O método run() retorna um ApplicationContext e este aplicativo, em seguida, recupera todos os beans que foram criados pela aplicação ou foram adicionados automaticamente graças ao SpringBoot. Note que o método run() recebe dois parâmetros: a classeApp::class.java e um *args, que detalharei melhor a seguir:
- App::class.java: (::) logo após o nome da classe indica que iremos pegar uma referência à classe por reflection. O (.java) indica que queremos uma referência Java e nãoKotlin;
- *args: * operador spread antes do array, insere todo o conteúdo do array no vararg do método run().
Vamos criar agora nossa configuração do Jersey. Crie uma arquivo Kotlin com nome de JerseyConfig e configure o Jersey como a seguir:
package org.kotlin.config import org.glassfish.jersey.server.ResourceConfig import org.springframework.context.annotation.Configuration /** * Created by Kleber on 04/08/2016. */ @Configuration open class JerseyConfig : ResourceConfig() { init { this.packages("org.kotlin") } }
Vamos aos detalhes:
- JerseyConfig : ResourceConfig(): herança e implementação de interfaces em Kotlin;
- init { … }: Bloco inicializador será criado junto com a instância da classe.
Para criar nossa endpoint, crie um pacote chamado API e dentro crie um arquivo Kotlin com o nome de JerseyAPI. Veja o exemplo:
ackage org.kotlin.api import org.springframework.stereotype.Component import javax.ws.rs.GET import javax.ws.rs.Path import javax.ws.rs.Produces import javax.ws.rs.QueryParam import javax.ws.rs.core.MediaType /** * Created by Kleber on 04/08/2016. */ @Component @Path("/jersey") class JerseyAPI { @GET @Path("/ola") @Produces(MediaType.APPLICATION_JSON) fun ola(@QueryParam("nome") nome: String): String { return "Olá, $nome, sou um ENDPOINT Jersey /GET" } }
Crie um arquivo chamado application.properties com o conteúdo abaixo dentro da pasta resources do projeto. Aqui diremos ao SpringBoot que o Undertow (WebServer) vai subir na porta configurada.
server.port=1010
Execute com um duplo click a task bootRun, na visão de Gradle do IntelliJ IDEA.
Abra um navegador e digite o seguinte na barra de endereços: http://localhost:1010/jersey/ola?nome=Mundo
Veja o resultado:
Olá, Mundo, sou um ENDPOINT Jersey /GET
E aí, deu certo? Se tiver qualquer dúvida, ou quiser dar alguma contribuição, fique à vontade nos comentários.
Espero que tenha gostado! Até a próxima.