Usando Kotlin para desenvolvimento de back-end: uma visão geral rápida
Publicados: 2022-03-11Não preciso apresentar o Kotlin aos desenvolvedores nativos do Android, pois em maio de 2017, o Google anunciou que seria o idioma oficial para o desenvolvimento do Android. Desde então, ganhou muita força como sendo a principal escolha de idioma para o desenvolvimento de aplicativos Android novos e brilhantes. Ele resolve muitos pontos problemáticos do Java, então os novos aplicativos são escritos principalmente nele e os antigos estão sendo reescritos nele.
Não há dúvida de que é ótimo no front-end dos aplicativos e, quando você menciona o Kotlin pela primeira vez, a maioria das pessoas o associa ao sistema operacional Android. No entanto, neste artigo, falarei sobre Kotlin como uma linguagem de back-end e gostaria de compartilhar minha história sobre a criação de um back-end Kotlin rápido, confiável e assíncrono para meu projeto de hobby Android. Não vou discutir sobre o que é o projeto, pois está fora do escopo deste artigo; em vez disso, vou me concentrar em explicar por que escolhi Kotlin e por que acho que é uma ótima linguagem para escrever aplicativos do lado do servidor ou APIs REST.
Por que Kotlin?
Deixe-me voltar ao início da minha jornada. Sempre tive ambições empreendedoras e pensei que o primeiro passo nesse caminho era criar algo por conta própria. Nada enorme, nada que mude o mundo, apenas algo pequeno que eu e talvez minha família e amigos possamos usar. Depois de ter uma ideia razoável, fui direto para ela e comecei a implementá-la. A primeira coisa que você faz no início de qualquer projeto é escolher suas ferramentas. Afinal, o conjunto certo de ferramentas pode economizar muito tempo e dinheiro a longo prazo. Então foi isso que eu fiz.
Eu sou principalmente um desenvolvedor Java. Escrevi vários sistemas back-end e APIs REST usando Java e Spring, e acho que esses dois são ótimas ferramentas para fazer essas coisas. Java por si só é uma linguagem abrangente, mas combinado com Spring, não há nada que você não possa implementar.
No entanto, há apenas um pequeno cabelo na sopa. Verbosidade. Embora o Spring e as versões mais recentes do Java ajudem bastante com isso, ainda assim você precisa lidar com muito código clichê. E como uma vez um grande cara me disse - o código mais seguro, confiável e livre de bugs é o código que não está escrito. Tomemos, por exemplo, esta classe Java trivial:
public class Person { private final String name; private final int age; public Person(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public int getAge() { return age; } }
Na minha opinião, isso é muito código para simplesmente dizer: “Quero uma classe com dois campos somente leitura”. A pior parte é que o construtor e os métodos foram gerados automaticamente. Ainda assim, quando você está revisando um pull request, você sempre passa por eles porque, bem, você nunca sabe se eles são o que você precisa ou não. Claro, isso pode ser encurtado com bibliotecas de terceiros como o Lombok, mas não seria bom se pudéssemos fazer isso fora da caixa? Vamos ver essa mesma classe exata em Kotlin:
class Person( val name: String, val age: Int )
É definitivamente mais curto e simples. As variáveis são finais, pois usamos a palavra-chave val ; o construtor e os getters são gerados em tempo de compilação. Se preferirmos não ter um objeto pessoa imutável, podemos simplesmente alterar val para var e voila, temos uma pessoa mutável, e tudo o que precisamos fazer é alterar apenas uma letra.
Minha segunda parte favorita em uma classe Java POJO simples é a substituição equals()
e hashCode()
. Eles são gerados automaticamente na maioria das vezes, mas você sempre precisa revisá-los, apenas para ter certeza. A boa notícia é que o Kotlin também pode lidar com isso. Basta alterar sua class
para uma data class
e você obtém equals()
e hashCode()
fora da caixa.
data class Person( val name: String, val age: Int )
Resumindo, apesar de adorar Java, queria criar um produto mínimo viável para o meu projeto o mais rápido possível em pouco tempo. E no caso de desenvolvimento de software, a maneira mais simples de conseguir isso é escrever menos código. Assim, minha busca por uma linguagem melhor para o desenvolvimento de back-end continuou. Com esse pensamento em mente, mudei primeiro para o Node.js. Ele tem algumas vantagens significativas—algumas linhas e seu servidor Express está funcionando, escutando na porta 8080 e respondendo com Hello World! cada vez que você envia uma solicitação de obtenção.
let express = require('express') let app = express(); app.get('/', (req, res) => res.send('Hello World!')); app.listen(8080);
Fácil, simples e rápido. Exatamente o que você esperaria de uma das linguagens de programação mais populares do mercado. Eu gosto de trabalhar com JavaScript e, por um breve momento, pensei que tinha encontrado a ferramenta certa, mas depois fiquei assombrado pelo fato de que JavaScript é digitado dinamicamente. Não me entenda mal, eu acho que a tipagem dinâmica é ótima no front-end, mas na minha experiência, ter um back-end de tipo estático simplesmente dá a você uma confiança extra de que seu servidor tem menos probabilidade de travar em tempo de execução devido a incompatibilidades de tipo . E vamos ser honestos aqui, quando seu back-end está atendendo várias centenas de milhares de usuários, você realmente não quer que isso aconteça. Node.js, no entanto, oferecia um ótimo recurso que eu queria manter, que é poder escrever facilmente código e serviços assíncronos.
Com esses requisitos em mente, optei por escrever meu back-end Android Kotlin também em Kotlin.
Kotlin: uma visão geral rápida
Para aqueles que nunca ouviram falar disso antes, Kotlin é uma linguagem de programação de código aberto e estaticamente tipada que suporta programação orientada a objetos e funcional. Ele fornece sintaxe e conceitos semelhantes como C#, Java ou Scala e visa principalmente a JVM, mas também possui variantes que visam JavaScript ou código nativo. É muito semelhante ao Java, pois o Kotlin/JVM compila para bytecode Java, portanto, para os engenheiros de back-end com experiência em JVM, o Kotlin será fácil de entender.

Como afirma sua página oficial, o objetivo do Kotlin não é ser único, mas buscar inspiração e melhores práticas de décadas de desenvolvimento de linguagem. Ele pode ser usado com qualquer IDE Java ou a partir da linha de comando, mas eu pessoalmente prefiro e recomendo usá-lo com o IntelliJ. Ele é mantido e atualizado ativamente pela equipe da JetBrains, e não se preocupe em comprar a versão paga - se você começou com Kotlin, a versão da comunidade do IntelliJ atenderá a todas as suas necessidades. Os três aspectos mais importantes do Kotlin que eu gostaria de destacar são: a) conciso (reduz drasticamente o código clichê), b) seguro (por um lado, é construído para evitar exceções de ponteiro nulo) e c ) interoperável (você pode aproveitar as bibliotecas existentes para JVM, Android ou navegador).
Corrotinas Kotlin
Todo mundo quer ter serviços que atendam os usuários rapidamente. Para atingir a capacidade máxima do seu servidor, a primeira coisa que você pode fazer é ter um aplicativo multithread. Java é bastante complicado com isso. Quando você aprende Java, primeiro aprende que, se quiser um aplicativo multithread, deve estender a classe Thread ou implementar a interface Runnable. Iniciantes nunca realmente entendem qual é a diferença (se houver alguma), mas para aumentar a confusão, eles também são instruídos a sempre iniciar um thread com o método run, nunca usar o método start. Ou espere, foi o contrário? Afinal, não importa, você não deve iniciar um thread manualmente de qualquer maneira, é muito caro, em vez disso, use um pool de threads. Simples, exceto que não é.
Felizmente, o Kotlin tem uma solução ainda mais simples chamada coroutines. Simplificando, as corrotinas tornam possível escrever código assíncrono e sem bloqueio de uma maneira muito fluente. A ideia central é ter funções que possam ser suspensas; em outras palavras, a computação pode ser suspensa em algum ponto e retomada mais tarde. A melhor parte é que ao escrever código não bloqueante, o modelo de programação realmente não muda, então escrever código não bloqueante é essencialmente o mesmo que escrever código bloqueante. Vejamos dois exemplos:
fun sendRequest(): Int { /* do some heavy work */ return 1; }
Este exemplo mostra uma função de bloqueio. O thread que executa esse trecho de código não fará nenhum outro trabalho até que a função retorne, o que no caso de uma API ou chamada de banco de dados pode levar alguns segundos. Nós realmente não queremos bloquear nosso encadeamento enquanto esperamos por outro serviço, então vamos transformar essa função em uma função sem bloqueio.
suspend fun sendRequest(): Int { /* do some heavy work */ return 1; }
Este exemplo mostra como podemos transformar nosso método em uma função sem bloqueio que pode ser suspensa. Isso significa que se, por simplicidade, o trabalho pesado for uma simples chamada de função delay()
de 10 segundos, o thread em execução continuará trabalhando em outras tarefas por esse tempo e retomará a execução da função após os 10 segundos. Código agradável e sem bloqueio obtido com uma palavra-chave.
Serviço Assíncrono com Ktor
Quando se trata de escrever APIs REST, há algumas etapas extras que devem ser executadas, como iniciar um servidor incorporado ou analisar a solicitação e, é claro, ninguém quer fazer isso manualmente. Java tem Spring Boot, o que facilita muito as coisas e, felizmente, Kotlin tem um framework chamado Ktor. Ktor é um framework web para construção de servidores assíncronos. Como afirma seu site, o Ktor é “fácil de usar, divertido e assíncrono”. Agora, diversão é subjetiva, então eu não gostaria de provar isso, no entanto, vamos ver um trecho que se mostra fácil de usar e assíncrono.
fun main() { embeddedServer(Tomcat, 8080) { routing { get { call.respond("Hello world!") } } }.start(wait = true) }
O exemplo acima apresenta um servidor Kotlin Ktor totalmente funcional que está sendo executado em um servidor Tomcat incorporado, escuta na porta 8080 e responderá de forma assíncrona com “Hello world!” para receber pedidos. Tudo isso em menos de 10 linhas de código.
Ktor obviamente pode fazer muito mais do que isso. Apresentar todos os recursos do Ktor requer seu próprio artigo, mas entre muitas coisas, facilita o login e a autenticação. Leia mais sobre o que o Ktor pode fazer no lado do servidor e como configurá-lo aqui.
Outros benefícios do Kotlin no back-end
O primeiro benefício que gostaria de destacar é que você pode usar bibliotecas Java no Kotlin e, acredite, existem muitas bibliotecas de terceiros incríveis para Java que podem facilitar sua vida. Por que você escreveria sua própria implementação quando existe uma biblioteca de código aberto pronta para uso que faz o trabalho perfeitamente? Usá-los com Kotlin funciona perfeitamente.
Outra grande vantagem do Kotlin e Ktor são as extensas bibliotecas e estruturas de teste que você pode usar. A estrutura Junit funciona como um encanto com o Kotlin, e o Ktor adiciona em cima disso sua própria biblioteca de testes que permite escrever testes de ponta a ponta e testes de integração rapidamente. Você pode usar um mecanismo de teste personalizado que executará todo o seu aplicativo e poderá lidar com solicitações da mesma forma que o aplicativo ativo faria.
Conclusão
Como mencionei anteriormente, sou principalmente um desenvolvedor de back-end Java com vários aplicativos do lado do servidor e APIs REST atrás de mim. Embora eu adore programar em Java, acho que não existe uma linguagem ou estrutura única que seja perfeita para qualquer trabalho e possa resolver qualquer problema. Minha abordagem é familiarizar-se com o máximo de ferramentas que puder e, quando surgir um problema, escolher a melhor ferramenta que possa resolver esse problema específico com perfeição.
Como afirma o site Kotlin, o objetivo do Kotlin não é ser único; em vez disso, ele se inspira e as melhores práticas de décadas de desenvolvimento de linguagem, e acredito que, quando se trata de desenvolvimento de back-end, Kotlin, Coroutines e Ktor formam um trio incrível para fazer o trabalho. Você pode ler mais sobre Kotlin e sua utilidade como linguagem de programação aqui.