No dia 12 de dezembro, tive a honra de participar da II Maratona das Live Coders Girls BR. Foram oito horas seguidas de lives com mulheres incríveis da comunidade compartilhando conhecimento e experiências sobre diversos assuntos da tecnologia. Inclusive, se puder, conheça e acompanhe esse time maravilhoso na Twitch.
Na ocasião, resolvi falar um pouco sobre como funciona o backend e como começar nesse mundo usando Kotlin, além de algumas outras ferramentas complementares para a criação de uma API bem simples.
Apenas um adendo: este artigo e a live não tiveram nenhuma intenção de fazer com que as pessoas achem que Kotlin é a única opção para começar no backend. Mas como é uma linguagem que estou aprendendo e usando profissionalmente, pretendo prosseguir meus estudos com ela e, assim, também compartilhar conhecimento.
Antes de qualquer coisa, vamos entender melhor o que é backend e como ele funciona. Normalmente, as pessoas descrevem o backend como algo que fica "por trás" de qualquer aplicação, aquilo que o cliente não vê diretamente.
Vamos incrementar um pouco mais essa descrição. Podemos dizer que backend é onde você vai estruturar, programar e definir regras de negócio e validações da sua aplicação. Também estarão suas conexões com banco de dados e com outras possíveis aplicações e APIs.
Mas, atenção: isso não significa que no frontend não existem regras, porque existem e são muito importantes para o bom funcionamento de uma aplicação.
Como citamos algumas vezes o termo API nessa conversa, vamos entender o que significa: Application Programming Interface. Ou seja, uma aplicação que você constrói para servir como uma interface e que poderá ser integrada ou utilizada por outros sistemas.
Prosseguindo, o backend funciona da seguinte forma: você constrói seu código e, nele, coloca toda a programação que, possivelmente, atenderá as regras de negócio solicitadas. Pode surgir a necessidade de fazer uma conexão a um banco de dados onde poderá consultar, alterar, salvar e deletar informações para o seu sistema. Além disso, você também percebe que seria interessante o seu código ter acesso a outros sistemas que podem complementar as funcionalidades necessárias para atender seus requisitos.
Então você prepara seu código para que consiga mandar requisições e receber respostas desses outros sistemas. Entendendo um pouco melhor:
Requisição (request): funciona como um pedido que o seu sistema faz a outro. Por exemplo: você pode pedir que o sistema retorne os dados do seu cliente a partir de uma consulta pelo CPF.
Resposta (response): é exatamente o que você receberá logo após a sua requisição. Este retorno pode ou não ter uma espécie de pacote com informações. Ou pode, simplesmente, te dizer qual foi o status daquela comunicação solicitada. Depende de como tudo foi desenvolvido para se comportar.
E além da comunicação ocorrer entre sistemas no backend, o frontend poderá consumir o que foi construído, fazendo requisições e recebendo respostas de acordo com cada regra construída:
Ok, agora que entendemos um pouco da teoria, acho que podemos começar a entender um pouquinho de algumas ferramentas que vamos utilizar neste exemplo.
Observação: Lembrando que não trata-se de uma defesa para o uso exclusivo do que será apresentado a seguir, mas apenas tecnologias que estou aproveitando para estudar. Cada um dos tópicos pode gerar um artigo separado ou uma live apenas falando sobre ele. Quaisquer dificuldades no entendimento, fiquem à vontade parar perguntar. A ideia é apenas apresentar o que vamos utilizar nessa nossa primeira API e, posteriormente, nos aprofundarmos nos assuntos levantados, ok?
Linguagem Kotlin: É uma linguagem de programação que foi criada pela JetBrains, mas que em 2017 foi adotada pelo Google como uma linguagem oficial para construção de aplicativos Android. Aqui está a documentação. Ela pode ser utilizada junto com o Java, inclusive, sua execução acontece pela JVM.
JVM (Java Virtual Machine): Máquina virtual do Java. Para executar programas construídos em kotlin, você precisará compilar seu código e ele será executado na JVM. Então, também é importante que você instale o JDK no seu computador.
Gradle: É um gerenciador de dependências e também nos auxiliará nos processos de build do código. Aqui está a documentação.
Spring: Ferramenta muito utilizada para construção de APIs no Java, mas também podemos utilizar no Kotlin. Não é a única forma de fazer isso, existem muitas outras. Mas neste momento, utilizaremos esta. Aqui está a documentação.
Intellij: Será nossa IDE nessa descoberta do kotlin. IDE é o software que você utiliza para escrever seu código e que te dará suporte para diversas funcionalidades que facilitam o trabalho de pessoas desenvolvedoras. Você pode fazer download da versão Community que é gratuita.
Ao abrir o Intellij, você poderá se deparar com a tela a seguir. Clique em "Projects" e, em seguida, "New Project":
Após isso, no lado esquerdo da tela, vamos escolher a opção "Gradle". Logo a direita, no início dessa janela, você deverá identificar e escolher a versão do JDK que tiver instalado em seu computador. Em seguida, um pouco mais abaixo, você encontrará diversos itens para escolher para desenvolver o seu projeto. Neste momento, vamos selecionar a opção Kotlin/JVM. Se houver alguma outra opção selecionada, basta clicar nela novamente, que não estará mais selecionada:
Clique no botão "Next" para prosseguirmos para a próxima etapa. Agora você já pode escolher um nome para o seu projeto no campo "Name". Seria muito sugestivo deixarmos como "meuPrimeiroCodigoKotlin"?
O campo "Location" te mostra onde, por padrão, serão salvos seus projetos no seu computador. Você pode alterar, se achar melhor.
Clique em "Finish" e seu novo projeto começará a ser criado. Lembre-se que estamos usando o Gradle, então espere alguns instantes, pois ele começará alguns processos para que as configurações sejam feitas automaticamente.
Quando tudo terminar, aparecerá uma aba na parte debaixo do Intellij mostrando que o build foi finalizado com sucesso:
Starting Gradle Daemon...
Gradle Daemon started in 5 s 154 ms
BUILD SUCCESSFUL in 1m 23s
Perceba que o seu projeto já possui uma estrutura montada:
Nós vamos construir nossa aplicação e toda a sua estrutura dentro da pasta "src". Em relação a pasta "java", você pode excluir tranquilamente. Vamos usar apenas a pasta "kotlin".
Bora, então, criar nosso primeiro arquivo nesse projeto! Clique com o botão direito na sua pasta "kotlin", escolha a opção "New" e, em seguida, clique em "Kotlin Class/File".
Na próxima janela que se abrirá, você poderá colocar o nome como "main". Após isso, selecione a opção "Class" e pressione a tecla "Enter" no seu teclado.
E, finalmente, bora para o código! Como é de costume, a primeira coisa que vamos codificar será o nosso famoso Hello World.
fun main() {
println("Hello World")
}
Logo ao lado esquerdo do seu código, você visualizará uma pequena seta verde. Clique nela e, em seguida, "Run MainKT".
O seu projeto começará a ser "construído", ou seja, o build terá início. Nas primeiras vezes, pode acontecer uma demora um pouco maior. Não se preocupe, é normal. Nas próximas vezes que precisar buildar seu projeto, isso não deverá acontecer novamente.
E, finalmente, você verá seu Hello World executado com sucesso! Mas, o que queremos de fato, não é apenas um hello world, então vamos em frente.
Neste primeiro exemplo, faremos apenas uma chamada que fará a soma de dois números. Por enquanto, não vamos nos preocupar com a pouca complexidade das regras que precisaremos colocar no código, mas sim, vamos nos preocupar nas estruturas que precisamos criar para que possamos, mais para frente, construir outros tipos de APIs.
A primeira coisa que precisamos fazer, é importar a dependência do gradle e adicioná-la em nosso projeto. Você pode entrar neste link. Escolha a versão da release mais recente e clique na aba "Gradle".
Copie as linhas que foram disponibilizadas e cole em seu projeto. Ou seja, abra o arquivo "build.gradle" procure o "bloco" de dependências:
Neste momento, caso o gradle esteja configurado para fazer o auto-import, ele buildará sozinho e importará corretamente o que foi adicionado. Caso não esteja, você pode selecionar a opção Gradle do lado direito da IDE ou clicar no ícone que o Gradle coloca em sua tela automaticamente. Quando você clicar, o novo build acontecerá.
Sua IDE apresentará a seguinte mensagem na parte debaixo. Aguarde o processo finalizar.
Agora, precisamos criar nossa classe para que possamos relacioná-la ao Spring. Então faremos o seguinte: antes da nossa função "main", vamos criar nossa classe e utilizar a anotação @SprintBootApplication:
import org.springframework.boot.autoconfigure.SpringBootApplication
@SpringBootApplication
class MinhaIncrivelAPI
fun main() {
println("Hello World")
}
Precisamos, agora, chamar o método correto dentro da "main" para que possamos utilizar o servidor que o Spring sobe automaticamente, utilizando o Tomcat. Então acrescentamos o runApplication<>():
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.runApplication
@SpringBootApplication
class MyIncredibleAPI
fun main() {
runApplication<MyIncredibleAPI>()
}
Neste momento, já pode ter algum erro acontecendo para você, dependendo da versão da JVM.
"Cannot inline bytecode built with JVM target 1.8 into bytecode that is being built with JVM target 1.6. Please specify proper '-jvm-target' option"
Caso isso aconteça, você precisará adicionar a referência à versão correta da JVM. Dentro do arquivo build.gradle, adicione o seguinte trecho que apontará para a versão correta da JVM que você precisa para utilizar o Spring da forma que estamos configurando:
compileKotlin {
kotlinOptions.jvmTarget = "1.8"
}
Após isso, você pode clicar novamente no load do Gradle para baixar a dependência adicionada e o erro não será mais um problema.
Aparentemente, já temos nosso Spring configurado e já podemos subir o servidor se quisermos. Vamos clicar em Run e testar:
Ops. Parece que ainda há algo de errado:
"Caused by: java.lang.IllegalStateException: Could not evaluate condition on org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration$EmbeddedDatabaseConfiguration due to org/springframework/dao/DataAccessException not found. Make sure your own configuration does not rely on that class. This can also happen if you are @ComponentScanning a springframework package (e.g. if you put a @ComponentScan in the default package by mistake)"
Precisamos ajustar duas coisas em nosso código: uma delas é relacionar nosso projeto a um pacote (package). A outra, é dizer que a nossa classe é do tipo open. Veja a seguir como ficará o código:
package myNewIncredibleAPI
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.runApplication
@SpringBootApplication
open class MyIncredibleAPI
fun main() {
runApplication<MyIncredibleAPI>()
}
Ao clicarmos em run novamente, tudo deverá funcionar normalmente:
Você pode perceber que o Spring subiu um serviço pelo Tomcat pela porta 8080. Se tudo deu certo, parabéns até aqui. Você pode parar a execução no botão de stop:
Vamos em frente. No formato como pretendemos criar essa nossa API que somará dois números, utilizaremos também uma controller. O objetivo principal dessa controller é cuidar do fluxo para onde sua API deve ser direcionada na aplicação que você está construindo. Por exemplo: se você precisa salvar algo no banco de dados, a sua API chegará pela Controller e, nela, será feito o direcionamento para um fluxo que fará as validações necessárias. Posteriormente, caso esteja tudo certo e de acordo com as regras desenvolvidas, o fluxo segue até a conexão com o banco de dados, onde as informações poderão ser salvas.
Para deixar nosso projeto mais organizado, criaremos um pacote e, por convenção da comunidade, o chamaremos de controllers. Clique com o botão direito na pasta "kotlin", escolha a opção "New" e "Package":
Defina o nome do seu pacote:
Agora, já temos onde criar nossa classe controller que cuidará da nossa API. Neste nosso primeiro exemplo, como faremos apenas a soma de dois valores, ainda não teremos nada muito complexo como fluxo. Mas não se preocupe, logo chegaremos lá.
Clique com o botão direito em cima do seu package, escolha "New" e, em seguida, "Kotlin Class/File":
Defina o nome da sua classe controller de acordo com a responsabilidade que ela possuirá. Lembre-se de tentar manter seu código o mais legível possível para que qualquer pessoa consiga entender a função de cada arquivo no seu projeto.
Importante: Neste caso, precisamos colocar o sufixo "Controller". Veja:
Pressione "enter" no seu teclado e sua classe será criada. E, provavelmente, terá algo parecido com isso:
package myNewIncredibleAPI.controllers
class CalculadoraController {
}
Reparou no nome do pacote logo em cima da sua classe? Vamos manter essa organização do nosso projeto.
Como estamos usando o Spring para facilitar nosso trabalho na criação da nossa primeira API, temos uma nova anotação para conhecer: @RestController. Ela fará com que aquela classe seja reconhecida e funcione como uma Controller, uma verdadeira cuidadora de rotas e fluxos! Veja como fica:
package myNewIncredibleAPI.controllers
import org.springframework.web.bind.annotation.RestController
@RestController
class CalculadoraController {
}
Uma outra anotação que não é obrigatória para a criação de uma nova rota, mas que vamos utilizar em nosso exemplo para aprender sobre ela é @RequestMapping.
package myNewIncredibleAPI.controllers
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController
@RestController
@RequestMapping("/calculadora")
class CalculadoraController {
}
Enquanto você vai adicionando novas anotações em seu código, a própria IDE pode te ajudar a fazer todos os imports necessários. Caso você tenha alguma dificuldade e isso não ocorra automaticamente, você pode fazer da seguinte forma: o Intellij já deixará seu código em uma cor diferente, sinalizando que há algum erro acontecendo. Neste caso, você pode colocar o cursor do mouse em cima do código com erro e uma pequena mensagem te indicará o que está acontecendo e o que a IDE te sugere que seja feito. Neste caso, o import.
Coloquei em nosso exemplo, como sugestão, uma rota definida: @RequestMapping("/calculadora"). Isso significa que, para alguém chegar até aquela controller, deverá utilizar a barra e a palavra calculadora. Veremos melhor quando tentarmos executar nossa API. Vamos prosseguir.
Agora que já temos a classe criada, precisamos escrever o código da nossa função que fará a soma dos dois números.
package myNewIncredibleAPI.controllers
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController
@RestController
@RequestMapping("/calculadora")
class CalculadoraController {
fun somar(valor1: Int, valor2: Int): Int {
return valor1 + valor2
}
}
Essa é uma forma de escrever o nosso método. Vou mostrar uma forma mais simples. Mas primeiro, vamos entender uma parte de cada vez do nosso código:
E aqui, podemos ver outra forma de escrever a função:
package myNewIncredibleAPI.controllers
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController
@RestController
@RequestMapping("/calculadora")
class CalculadoraController {
// forma 1 de escrever a função
fun somar(valor1: Int, valor2: Int): Int {
return valor1 + valor2
}
// forma 2 e simplificada
fun somarValores(valor1: Int, valor2: Int) = valor1 + valor2
}
Para nosso função, também será necessário utilizarmos uma anotação do Spring. Neste caso, vamos usar a @GetMapping("/somar"). Definimos aqui também, mais um "pedacinho" da sua rota, além de definirmos o verbo que sua API utilizará.
Vamos entender alguns pontos:
A rota que estamos escrevendo do @RequestMapping e no @GetMapping ajuda o seu código a entender qual é o caminho mapeado que a sua API deverá seguir, para ser direcionada para seu objetivo.
As APIs possuem verbos para que possamos definir melhor qual é o seu comportamento. Em nosso exemplo, estamos utilizando o "Get", pois queremos apenas receber o resultado de volta. Existem outros verbos que aprenderemos melhor mais para frente.
package myNewIncredibleAPI.controllers
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController
@RestController
@RequestMapping("/calculadora")
class CalculadoraController {
@GetMapping("/somar")
fun somarValores(valor1: Int, valor2: Int) = valor1 + valor2
}
Nossa primeira API parece pronta, certo? Vamos testar? Bora, coragem! Já sabemos o que precisamos fazer: ir até a nossa classe mais importante (a main) e clicar em "Run". Isso colocará nosso serviço de pé!
Deu certo? Então vamos para o próximo passo.
Observação:
Caso não tenha dado certo, posso te sugerir algumas coisas. Uma delas é, pode ficar em paz. Erros acontecem o tempo todo enquanto estamos programando, é normal se deparar com diversos deles.
Outra coisa que posso te sugerir é tentar entender o erro. Se não conseguir, talvez realizar pesquisas pode te ajudar. Lembre-se de que nem sempre o primeiro resultado das pesquisas pode ser o que você precisa. Sem problemas continuar pesquisando.
É importante ter em mente também que é legal revisar seu código. Dê uma repassada em cada passo que você fez. Explique para si (ou para outra pessoa, isso também ajuda) o que foi feito. Muitas vezes, refazer o pensamento te ajuda a enxergar o que aconteceu.
E, por mais boba que pareça essa próxima dica, acredite! Ela funciona em diversas ocasiões. Às vezes nos acostumamos com o erro e não conseguimos ver além do que está ali. Isso também é completamente normal. Apenas o fato de você sair um pouco da frente da tela do seu computador, beber uma água, respirar fundo e voltar, já pode ajudar a limpar seus pensamentos e, quando você voltar, há grandes chances de entender o que aconteceu.
Não tenha medo de pedir ajuda! Qualquer dúvida que tenha é válida e deve ser tirada. A comunidade sempre pode ajudar.
Ok. Precisamos "chamar" nossa API, certo? E ver se ela nos retorna o que queremos que ela retorne. Você pode fazer isso direto do seu navegador ou utilizando alguma ferramenta. Eu, particularmente, gosto muito do postman.
Como rodamos nosso projeto, o servidor está "de pé" e conseguirá "nos ouvir" quando chamarmos, quer ver?
Lembra que o Spring utilizou o Tomcat para subir um servidor e nos deu o seguinte endereço para utilizarmos: http://localhost:8080. Vamos ver o que acontece se chamarmos dessa maneira:
Ocorreu um erro! Existem diversos códigos de erros que podemos receber, mas neste caso, a API nos retorno 404. Isso aconteceu, porque na realidade não temos nada mapeado para retornar quando chamarmos a "raiz" da nossa rota. O código 404 significa que o caminho para aquela rota não foi encontrado. E faz sentido, certo? Lembra que nós mapeamos mais alguns pedacinhos do caminho total que precisamos chamar para executar nossa API? Eram /calculadora e /somar. Então vamos incrementar nossa chamada:
Outro erro aconteceu! Apesar da nossa rota parecer correta, vamos analisar novamente como fizemos nossa função:
@GetMapping("/somar")
fun somarValores(valor1: Int, valor2: Int) = valor1 + valor2
Ok. Analisando nosso código, definimos que precisamos de dois tipos de entrada: valor1, do tipo inteiro, e valor2, também do tipo inteiro. Então é isso! A API retornou 500, pois o servidor não entendeu muito bem o que estávamos querendo fazer. Agora vamos colocar os valores como parâmetro que faltam e ver o que acontece.
Logo abaixo de onde você digita o caminho da sua API, você terá uma aba chamada "Params". Preencha com os nomes dos campos e valores que você gostaria de colocar:
Ou, se preferir, escreva a rota da seguinte forma:
http://localhost:8080/calculadora/somar?valor1=10&valor2=20
Agora deu certo! Veja que a API nos retornou o status 200 (que significa que funcionou com sucesso) e também nos deu a resposta da soma dos dois valores que colocamos.
Caso não tenha dado certo, volte naquelas dicas que coloquei mais acima deste artigo. Espero que consiga e comemore quando der certo!
Qualquer dúvida que tenha ficado, fiquem à vontade para perguntar. O que puder, ajudarei. Caso eu não possa, tenho certeza que a comunidade conseguirá. E se for algo que eu não souber, sem problemas, podemos pesquisar e aprender!
Imagino que o artigo tenha ficado um pouco grande, mas a ideia era passar por cada passo e cada erro que eu vi acontecendo para que pudéssemos entender o que fazer. Claro que podem acontecer outros erros, mas podemos aprender a resolvê-los.
Fiquem à vontade para dar feedback e para me contar se conseguiram executar seu primeiro código utilizando Kotlin no backend! Até a próxima!
Top comments (2)
Consegui fazer minha primeira API seguindo esse artigo!
Muito obrigada por compartilhar! 🖤
Ah, que coisa maravilhosa de se ler. Tô com o coração quentinho por saber disso. Que os novos passos no Kotlin sejam incríveis! <3