Boas-vindas ao curso de Kotlin: criando aplicações resilientes e assíncronas!
João: Olá! Me chamo João Victor, sou desenvolvedor Java e Kotlin. Tenho desenvolvido trabalhos aqui na Alura sobre essa linguagem.
Paulo: Me chamo Paulo Silveira, sou CEO da Alura. Uma honra estar apresentando este curso com o João.
João Victor é uma pessoa de pele clara, olhos escuros e cabelos pretos curtos, usa bigode e cavanhaque. Veste uma camiseta azul marinho com o texto "Alura", em branco. Está sentado em uma cadeira preta e, ao fundo, há uma cortina preta do lado esquerdo e do lado direito uma estante com algumas plantas e decorações.
Paulo Silveira é uma pessoa de pele clara, olhos escuros e cabelos castanhos escuros. Usa bigode e cavanhaque, e um óculos preto. Veste uma blusa de frio preta lisa, e está sentado. Ao fundo, há uma parede azul clara na parte superior e amarela na parte mais inferior.
Paulo: Essa é uma formação que estamos abordando todos os problemas em Kotlin, com um projeto grande que envolve várias tecnologias.
Neste primeiro curso, vamos ter um enorme desafio. Isso porque, no cotidiano, trabalhamos com várias tecnologias assíncronas. Por isso, em um primeiro momento, usaremos o Retrofit para consumir o web services.
Pode até ser um web service que nós mesmos criamos, mas também pode ser um que você queira usar pronto.
Em seguida, vamos entender melhor sobre mecanismos de trabalho assíncrono, porque seja no front-end ou back-end é necessário entender essas chamadas assíncronas.
Até com rotinas, algumas pessoas se limitam a copiar e colar, usando recursos de Kotlin mais avançados para chegar em testes. Tudo isso com um projeto já iniciado em Spring. Isso torna o cenário bastante real, não é, João?
João: Sim, torna o cenário bem parecido com um corporativo. Toda essa parte de testes atualmente é um ponto fundamental para se ter um código com qualidade para ter garantia de que está funcionando. Assim, é possível verificar isso através de testes.
Sobre os mecanismos de trabalhos assíncronos, atualmente é impossível, em grandes projetos, usar requisições síncronas. Desse modo, sempre tentamos trabalhar com as requisições assíncronas.
Paulo: Às vezes acho que até nos pequenos projetos, em alguns casos as pessoas acabam não sabendo o motivo de ter feito daquela forma, como o motivo de usar promise do JavaScript ou callbacks do Kotlin.
Mas precisamos ter esse conhecimento e acredito que ficou muito legal este curso. Isso porque será útil e prático, porque vamos consumir web services, endpoints e APIs e fazemos isso o tempo todo em cenários reais.
Faremos tudo isso usando estruturas que muitas pessoas estão trabalhando a um certo tempo, como Kotlin e Spring, e ainda não dominam tudo sobre essas ferramentas.
Acredito que seja uma oportunidade para mostrar que estamos evoluindo nesse ecossistema de Kotlin, de back-end, de assíncrono e abraçando cada vez mais essa comunidade com a ajuda do João Victor.
João: As ferramentas que abordaremos ao longo deste curso, são tecnologias usadas no mercado. Caso você seja contratado por uma grande empresa e esteja trabalhando com Kotlin, muito provavelmente verá essas mesmas tecnologias que falaremos neste curso na empresa.
Para quem quer seguir a carreira em Kotlin, recomendo que conclua esse curso. Aprenderemos sobre o* Retrofit* para aplicá-lo à chamada HTTP de uma grande empresa. Os testes com Kotest também são utilizados pelas empresas para testes de unidade.
Assim como o Coroutines, que atualmente vem ganhando espaço no mercado com as questões de threads virtuais. Inclusive, o Java está trazendo isso como recurso para ele também.
Temos uma biblioteca nativa completa para chamadas síncronas com Kotlin. Este é um curso bem interessante, voltado para o mercado e recomendado para quem deseja trabalhar com Kotlin.
Paulo: Preste atenção, temos muitos links nas tarefas do curso, com o código base, para o boilerplate ("chapa de ebulição"). Nesse caso, podemos nos limitar a copiar e colar.
Principalmente nessa primeira aula, em que estarei junto com o João, vou fazer diversos questionamentos para irmos linha por linha dos códigos, mesmo que seja um código que não será usado muitas vezes, para entendermos com profundidade o que está acontecendo, já que teremos bastante código envolvendo esse projeto em Spring.
Boa aula!
Paulo: João Victor, acho que um cenário clássico quando trabalhamos com linguagem do back-end e também com mobile, é consumir muitos serviços. Acredito que seja uma realidade no cenário de arquitetura.
Em alguns momentos, sequer sabemos que estamos consumindo serviços, mas estamos chamando uma API que consome um serviço por trás, por exemplo. Logo, é um ponto que precisamos saber para aplicar no cotidiano.
O Retrofit aplica isso com muita facilidade, porque existe a API nas bibliotecas padrão do Java e do Android, para trabalhar com requisição HTTP. Mas elas costumam ser de baixo nível e é necessário escrever bastante código para executar um método get
ou post
.
O nosso objetivo é trabalhar com Kotlin e Retrofit para facilitar esse processo, João?
João: Exatamente.
Como você bem mencionou, atualmente temos diversas formas de fazer esse tipo de requisição. Principalmente porque hoje trabalhamos com arquiteturas de microsserviços, em que um microsserviço chama outros. Precisamos sempre trabalhar com esse tipo de requisição.
Assim, temos desde bibliotecas que fornecem isso de uma forma mais simples, e outras que o fazem de maneira mais complexa. Esta última, sempre exige que escrevamos mais código.
No desenvolvimento de software, a ideia é focar nas regras de negócio e menos em detalhes de implementação. Logo, o Retrofit chega exatamente com essa abordagem: com a biblioteca conseguimos inserir essa dependência e, com isso, diminuir a quantidade de código manual. Podemos somente incluir as configurações necessárias para conseguir consumir um serviço.
Esse é o principal objetivo do Retrofit: simplificar o código.
Paulo: João, tenho certeza que você preparou o web service que vamos consumir.
Navegando na documentação do Retrofit, li que o exemplo principal é a API padrão do GitHub. Essa API lista os repositórios de uma pessoa, analisa os amigos que estamos deixando de seguir, quem começa a nos seguir, as estáticas, e mais. Estamos mais acostumados a trabalhar com isso, que facilita a leitura da documentação da API.
Neste curso, podemos escolher a API que desejarmos consumir e gerar o código de forma automática. Cada um pode escolher o seu, mas acredito que você, João, tenha um problema para analisarmos nessa formação avançada de Kotlin.
Qual é esse problema que teremos que desenvolver ao longo deste treinamento?
João: A pessoa pode usar a sua API, mas eu trouxe um exemplo que vamos pesquisar sobre carros em estoque que serão inseridos na aplicação. Eles não serão inseridos via banco de dados, mas sim no contexto da nossa aplicação.
Deste modo, faremos uma requisição para esse microsserviço que pode retornar, por exemplo, se determinado modelo de carro está disponível em estoque. Trabalharemos dessa forma para dar o contexto da nossa aplicação e ao acrescentarmos novos recursos.
Mas nada impede de adicionar outro contexto ou criar outra aplicação, com outro contexto, e consumir a API do GitHub, por exemplo.
No Retrofit, precisamos apenas mapear os campos desejados que estarão na API pública. Queremos trazê-los para a nossa aplicação. Criamos um objeto sem muitos problemas para trazer essas informações para dentro da nossa aplicação.
Paulo: Pelo que entendi, vamos trabalhar com anotações, seja em Kotlin ou Java. Assim, conseguimos configurar de uma maneira fácil, mesmo em casos específicos?
Porque imagino que usar um método get
para listar todos os carros disponíveis, deve ser simples com uma anotação que prepara um método para nós.
Porém, e se tivermos uma configuração, uma classe ou objeto mais complexo, como uma data com timestamp ou, até mesmo, ter que passar uma chave privada para exibir o token para ser autenticado para entrar na API.
Nesses casos que aparecem bastante, o Retrofit nos dá essas possibilidades?
João: Sim, e sem o uso de anotações!
No Retrofit não precisamos usar anotações, conseguimos montar uma classe de configuração da sua aplicação.
Por exemplo, sobre o token, conseguimos abrir um interceptor
na classe de configuração, em que passamos para ele que ao fazer a requisição para determinada API, é necessário passar um token específico. Isso de forma declarativa no código.
Atualmente, há quem prefira ler no código o que está sendo executado. Logo, é usado o interceptor
e inserido o token, e, ao realizar a requisição, o Retrofit consegue injetar todas essas informações necessárias para chamar a API e a requisição é feita com sucesso.
Paulo: É uma abordagem diferente, porque outros frameworks priorizam um monte de anotações. Com isso, ficamos com as classes com dez anotações para explicar como converter, como passar token, e assim por diante.
É uma vantagem diminuir o código. Eu vi alguns exemplos nos vídeos e me perguntei "Como ele sabe qual é o user?". Alguém escreveu o interceptor
ou o objeto é tão óbvio do JSON para o objeto, que ele faz sozinho.
João: Era esse o principal problema: tínhamos muitas anotações. Por exemplo, na classe tinha dez anotações e, por mais que elas sejam práticas por trazer menos código escrito, gera um pouco de dúvida.
Isso porque não sabemos muito bem o que o código está executando. Caso seja necessário debugar, como seria feito? Logo, o uso de anotações acabou ficando complexo por isso.
Programação declarativa: escreve o suficiente.
Agora, vamos mais para a programação declarativa, em que escrevemos o suficiente para entender o que o código está executando e debugar.
Assim, o Retrofit é isso: criamos uma interface e quando for necessário, o Retrofit vai implementar essa chamada HTTP.
O Retrofit por trás, com as suas classes de configuração, vai saber que ao fazer aquela chamada para o web service ou API externa, ele vai implementar, em tempo de execução, aquela interface e trazer as informações.
Do nosso lado, precisamos ter um mapeamento dos campos que chegam da API, se não o JSON não consegue realizar o parse
. Ele precisa saber que determinado objeto é o objeto que está vindo da API.
É essa abordagem que o Retrofit traz: poucas anotações de forma declarativa que nos permite debugar e conseguir visualizar o que o código está executando.
Paulo: Independente de trabalhar com smartphones ou no back-end com Spring e Kotlin, este curso é importante para entendermos como consumimos* APIs*.
Para aprendermos, também, essas vantagens do Retrofit, e encaixá-las no nosso projeto.
Vamos para a parte do código.
Espero vocês na próxima aula!
Paulo: Agora que o João está com um notebook, vamos conseguir analisar essa API de carros em estoque que ele preparou para nós trabalharmos ao longo deste curso.
Falando um pouco sobre o Postman, tem bastante artigo e cursos sobre essa ferramenta para explorarmos as APIs aqui na plataforma da Alura.
O Postman é mais prático do que ir à linha de comando e executar os comandos para enviar solicitações HTTP. É no Postman que acessaremos a *API *que você preparou, João?
João: Para o nosso contexto, trouxe uma aplicação em que teremos alguns carros para alugar, mas dessa aplicação precisamos consumir uma API.
A API é essa que está na tela do Postman. Se formos ver o cars-inventory
, é onde teremos como buscar por modelo. Se começarmos buscando no Postman, que atualmente é a* IDE* de requisição HTTP mais usada, faremos uma requisição para essa API para nós analisarmos o retorno.
Estamos com o Postman aberto com o método get
e o seguinte endereço:
http://ec2-18-215-156-13.compute-1.amazonaws.com:8080/cars-inventory?model=go
Abaixo, estamos na aba "Params" ("Parâmetros") em que temos uma tabela com uma coluna "key" com um valor "model", uma coluna "value" com "gol" e uma coluna chamada "description" vazia.
Por exemplo, no Postman, clicaremos no botão azul "Send", do lado direito do endereço para visualizarmos o que há no estoque. Note que abaixo, em "Body > Pretty", nos retornou:
[
{
"id": 158,
"make": "VW",
"model": "Gol",
"year": 2008,
"fuelType": "Gas"
},
//retorno omitido
Paulo: Já enviamos um ?model=go
, logo pela carry string já é possível indicar que essa API funciona mais ou menos assim.
Mas é assim que funciona no cotidiano: recebemos uma API com uma documentação, se vier. Majoritariamente recebemos o exemplo e precisamos investigar o que enviar de requisição e qual o retorno.
Esse endereço poderia ser acessado pelo navegador, João?
João: Sim! Quando estamos nos referindo a uma requisição get
, podemos acessar via browser. Porém, acredito que o Postman seja mais interativo para fazermos isso.
Por exemplo, você mencionou que estamos usando um query params ("parâmetros de consulta"), em que inserimos uma interrogação e tudo que colocamos depois dela, no caso model
, podemos mudar o valor: ?model=go
.
Note que no caso é o modelo é "Gol", mas podemos alterar para outro modelo de carro.
Perceba que abaixo do endereço, na aba "Params", ele nos retorna na coluna "Value" o modelo gol. O Postman nos traz essa facilidade, ao invés de trocarmos pela query conseguimos pelo value (valor).
Podemos dar um duplo clique em "gol" e digitar "ferrari". Note que, na URL, agora, temos:
http://ec2-18-215-156-13.compute-1.amazonaws.com:8080/cars-inventory?model=ferrari
Ao clicarmos novamente no botão "Send", o retorno é somente []
. Isso significa que não temos na nossa API nenhum carro do modelo Ferrari.
Isso é significativo, dado que, ao trabalharmos com parâmetros e buscarmos por algum que não temos em estoque, nos retorna vazio e não uma exceção. Foi feita uma requisição com sucesso, com o status: 200 OK
, mas que nos devolve um valor vazio, o que não é um erro.
Paulo: Muitas vezes retornar vazio não significa um erro. Há muitas APIs que até fazem sentido isso, inclusive, nesse caso de buscar em estoque por determinado modelo de carro.
João: Pode ser que depois de um tempo, em um cenário de expansão da empresa, tenha um modelo de carro da Ferrari. É uma forma flexível de aplicar, pois permite que a aplicação retorne caso tenha esse modelo.
Por exemplo, podemos alterar novamente para "gol" na URL:
http://ec2-18-215-156-13.compute-1.amazonaws.com:8080/cars-inventory?model=go
Em seguida, clicamos no botão "Send" mais uma vez.
[ { "id": 1757, "make": "VW", "model": "Gol", "year": 2008, "fuelType": "Gas" }, { "id": 557, "make": "VW", "model": "Gol", "year": 2017, "fuelType": "Gas" } [
Assim, temos as informações desse carro, como o ID, a marca, o modelo, o ano e o tipo do combustível.
Paulo: Há mais de um carro do modelo gol no estoque?
João: Isso, há mais de um modelo gol no estoque.
Podemos procurar por outro modelo, por exemplo, o Cruze: ?model=cruze
. Após alterar na URL, clicamos no botão "Send" novamente, para visualizarmos as opções em estoque do modelo Cruze.
[ { "id": 1146, "make": "GM", "model": "Cruze", "year": 2014, "fuelType": "Gas" } ]
Nesse caso temos somente um carro. Isso quer dizer que se for alugado, será retirado do estoque e não teremos mais carros desse modelo.
Essa é a ideia de consumir essa API, passando os parâmetros para pesquisar pelos carros que desejo alugar. Vamos supor que somos o cliente e queremos alugar um carro do modelo Cruze, ao visualizarmos haver esse modelo no estoque, alugamos o carro.
É essa a ideia da API de trazer quais modelos temos disponíveis no estoque.
Paulo: Cada vez que digitarmos um modelo, estamos acessando o endpoint (um dos pontos da API)?
Essas palavras confundem e tratamos tudo como sinônimo: web service, API e endpoint, mas cada um possui um significado específico.
Enfim, o endpoint é um dos pontos do nosso serviço de aluguel de carros. Estamos acessando esse modelo Cruze passando os parâmetros necessários.
Inclusive, se clicarmos na aba "Raw", conseguimos visualizar o que a requisição HTTP retornou.
[{"id":1146,"make":"GM","model":"Cruze","year":2014,"fuelType":"Gas"}]
João: Isso mesmo.
Paulo: Note que devolveu todos os campos na mesma linha. Em algum lugar do Postman também conseguimos visualizar o body ("corpo"), no menu superior após a aba "Headers".
Body
none: marcado
Não era isso que eu queria no retorno, queria visualizar o* body completo, com o *response ("resposta") e outras informações. Conseguimos visualizar essas informações no Postman?
João: Nesse caso, no body, vamos visualizar mais quando queremos enviar a requisição.
Paulo: Aquele body era para fazer a requisição, certo?
João: Isso mesmo.
Para visualizarmos a informação completa, vamos clicar na aba "Headers" no menu mais abaixo, não no "Headers" abaixo da URL.
Headers:
KEY | VALUE |
---|---|
Content-Type | application/json |
Transfer-Encoding | chunked |
Date | Thu, 29 Sep 2022 17:02:54 GMT |
Keep-Alive | timeout=60 |
Connection | keep-alive |
Paulo: Perfeito.
João: Na aba "Headers" conseguimos visualizar o tipo do conteúdo, o content type. É comum nesses endpoints que ao consumirmos alguns serviços, retorne no formato JSON. É possível retornar outro formato, porém, o normal é o JSON e é o que a nossa API está devolvendo.
Perceba que do lado superior direito da aba "Headers", temos o status 200 OK
. Isso é um ponto legal do Postman, se colocarmos o mouse sobre "Status: 200 OK", aparece uma mensagem explicando o que significa esse status.
Muitas pessoas que estão começando não conhecem ainda o que significa o status 200 OK
. Se fizermos uma requisição da API pelo navegador, teremos o mesmo resultado do endpoint retornando um payload. Mas e o 200 OK
?
Na mensagem informa que é um retorno de sucesso para requisições HTTP.
Vamos forçar um erro para analisarmos juntos. No endereço, removeremos a parte do parâmetro, ?model=cruze
, e clicaremos no botão "Send", do lado direito.
Repare que agora o status está como 400 Request
, na cor verde. Isso significa que faltou informação, não conseguimos acessar a API sem nenhum parâmetro no endereço.
Caso desejarmos saber o que é esse status, basta colocar o mouse por cima de "Status: 400 Request". Será exibida a seguinte mensagem:
400 Bad Request: The request cannot be fulfilled due to bad syntax ("A solicitação não pode ser atendida devido à sintaxe incorreta").
Desse modo, conseguimos identificar o motivo do problema.
Paulo: Perfeito.
Isso nós descobrimos, em muitos casos, na documentação ou vamos testando para analisar no próprio Postman. O JSON é flexível, mas também é um pouco trabalhoso por termos que realizar alguns testes para verificar se determinado parâmetro é obrigatório ou não, etc.
Essa palavra "payload" que você mencionou, é a parte do body (sem os headers) que chega no formato JSON?
João: Exatamente.
Para visualizarmos esse payload, vamos voltar com o endereço com o modelo "gOL", clicar no botão "Send" e depois na aba "Body", mais abaixo.
[ { "id": 25, "make": "VW", "model": "Gol", "year": 2008, "fuelType": "Gas" }, { "id": 840, "make": "VW", "model": "Gol", "year": 2017, "fuelType": "Gas" } [
O retorno da API é esse payload.
Têm pessoas que chamam de payload, outras de body ou resultado/retorno da API. Todos esses termos se referem a mesma coisa: os campos que mostram as informações mais necessárias do endpoint que estamos chamando.
Paulo: Agora, para pegarmos isso no código Java e Kotlin, usaremos o Retrofit porque é uma biblioteca muito usada. Assim como é comum em JavaScript as pessoas usarem a fetch API, padrão nos navegadores.
Mas para várias plataformas existem várias bibliotecas. De novo, caso você prefira usar outra plataforma, fique à vontade.
Este treinamento é legal porque, independente de utilizar o Retrofit ou não, apesar de aconselharmos, fica o conhecimento sobre consumo e uso de serviços, de payloads, dos headers e a transformação do JSON. Correto?
João: Isso mesmo.
Nós recomendamos o uso do Retrofit, mas nada impede você de usar outras plataformas para realizar este treinamento.
Paulo: Vamos configurar o Retrofit no projeto Kotlin para consumir esse serviço?
João: Vamos, sim, na próxima aula.
Te espero lá!
O curso Kotlin: aplicações resilientes e assíncronas possui 148 minutos de vídeos, em um total de 38 atividades. Gostou? Conheça nossos outros cursos de Kotlin em Programação, ou leia nossos artigos de Programação.
Matricule-se e comece a estudar com a gente hoje! Conheça outros tópicos abordados durante o curso:
Impulsione a sua carreira com os melhores cursos e faça parte da maior comunidade tech.
1 ano de Alura
Assine o PLUS e garanta:
Formações com mais de 1500 cursos atualizados e novos lançamentos semanais, em Programação, Inteligência Artificial, Front-end, UX & Design, Data Science, Mobile, DevOps e Inovação & Gestão.
A cada curso ou formação concluído, um novo certificado para turbinar seu currículo e LinkedIn.
No Discord, você tem acesso a eventos exclusivos, grupos de estudos e mentorias com especialistas de diferentes áreas.
Faça parte da maior comunidade Dev do país e crie conexões com mais de 120 mil pessoas no Discord.
Acesso ilimitado ao catálogo de Imersões da Alura para praticar conhecimentos em diferentes áreas.
Explore um universo de possibilidades na palma da sua mão. Baixe as aulas para assistir offline, onde e quando quiser.
Acelere o seu aprendizado com a IA da Alura e prepare-se para o mercado internacional.
1 ano de Alura
Todos os benefícios do PLUS e mais vantagens exclusivas:
Luri é nossa inteligência artificial que tira dúvidas, dá exemplos práticos, corrige exercícios e ajuda a mergulhar ainda mais durante as aulas. Você pode conversar com a Luri até 100 mensagens por semana.
Aprenda um novo idioma e expanda seus horizontes profissionais. Cursos de Inglês, Espanhol e Inglês para Devs, 100% focado em tecnologia.
Transforme a sua jornada com benefícios exclusivos e evolua ainda mais na sua carreira.
1 ano de Alura
Todos os benefícios do PRO e mais vantagens exclusivas:
Mensagens ilimitadas para estudar com a Luri, a IA da Alura, disponível 24hs para tirar suas dúvidas, dar exemplos práticos, corrigir exercícios e impulsionar seus estudos.
Envie imagens para a Luri e ela te ajuda a solucionar problemas, identificar erros, esclarecer gráficos, analisar design e muito mais.
Escolha os ebooks da Casa do Código, a editora da Alura, que apoiarão a sua jornada de aprendizado para sempre.