Alura > Cursos de Mobile > Cursos de Flutter > Conteúdos de Flutter > Primeiras aulas do curso Flutter: utilizando o Dio para realizar a comunicação com Web API

Flutter: utilizando o Dio para realizar a comunicação com Web API

Entendendo DIO e HTTP - Apresentação

Olá, boas-vindas a este é mais um curso de Flutter com Dio com o instrutor Ricarth Lima.

Audiodescrição: Ricarth é um homem de pele dourada, cabelo volumoso e crespo, óculos de armação escura, tem uma barba espessa e usa uma camisa de cor escura. Ele está à frente de uma parede lisa com iluminação rosa e azul.

Se você chegou aqui sem saber o que é DIO, saiba que DIO é um dos pacotes mais usados para comunicação com a Web API do Flutter. E qual será o nosso projeto? Vamos criar uma lista de compras que planejamos antes de ir ao supermercado para evitar surpresas ao chegar no caixa, o Listin.

Este projeto é uma continuação direta do curso anterior, mas você não precisa ter feito o curso de Drift e de Hive para assistir a este. No entanto, é necessário conhecer nosso projeto.

Então, vamos dar uma olhada nele. Temos nossas feiras, que são listas de compra e, quando clicamos em alguma delas, aparecem todos os produtos. Essa é a base do Listin, assim que já vem para nós.

Mas não queremos que essas informações, minha lista de compras, meus produtos, fiquem salvas apenas localmente. Vamos ter que enviá-las para a nuvem e é exatamente isso que vamos fazer com este botão de ícone de nuvem na lateral superior direta.

O que vamos aprender?

Se clicarmos nele, veremos que temos a opção de enviar para a nuvem, de sincronizar com a nuvem, ou seja, pegar tudo que está na nuvem, salvar localmente e de remover todos os dados da nuvem, o que sabemos que é importante por todas as questões de proteção de dados.

E como vamos fazer isso? Vamos aprender as operações básicas do HTTP, como GET, POST, PUT, DELETE, tudo isso usando o Dio. Vamos aprender a padronizar, para deixar o código cada vez mais modular, mais legível, o que é extremamente importante quando você está lidando com código em produção.

Vamos aprender também a usar interceptadores para gerar logs. Na vida real, também é muito importante que, quando uma requisição é enviada, quando a resposta é recebida, haja um interceptador para adicionar uma autenticação, para fazer um log, para fazer auditoria e assim por diante.

Vamos aprender isso também, é claro, a tratar erros. Quando lidamos com o ambiente externo, como é a internet, erros podem acontecer. Então, vamos tratar esses erros e exceções para que não apareçam na tela da pessoa usuária e a aplicação da sua empresa possa ter uma interface cada vez mais agradável e segura.

Para quem é este curso?

E quais são os pré-requisitos para você fazer esse curso? Você precisa ter uma boa base de Dart e de Flutter. Por isso, recomendo que você tenha feito a formação Dart e Flutter aqui da Alura.

E também vale dizer que vamos entregar o projeto já pronto de onde ele partiu no curso anterior. Por isso, você não precisa ter visto o curso anterior para entender este de Dio.

Agora que já entendemos muito bem qual o nosso projeto e o nosso desafio, vamos colocar a mão na massa!

Entendendo DIO e HTTP - Conhecendo o projeto

Agora que já nos conhecemos, vamos conversar sobre alguns detalhes que serão bem importantes para que o curso flua tranquilamente.

A primeira coisa é falar sobre o projeto de fato, como ele vai estar na base. No vídeo anterior, vimos o resultado final. Agora, vamos ver como vamos pegar esse projeto para implementar a funcionalidade de salvar na nuvem.

A lógica de funcionamento do projeto

Então, esse projeto é o Listin, aquela lista de compras onde colocamos nossas listas, que chamamos de Listins. Aqui temos a Feira de Caruaru, a de Mangaio, uma feira mensal. Podemos criar, editar, remover essas listas.

E, quando criamos uma delas, podemos entrar nela. Nela, planejamos alguns produtos, como leite, ovos, chocolate, trigo, fermento. Também podemos editá-los, removê-los, adicioná-los e por aí vai. Se dermos um check, ele vem para no carrinho. Se ele tiver um valor e uma quantidade, esse valor é somado no total.

Mas qual é a lógica por trás desse projeto? Para mostrar essa lógica, temos um diagrama de dados. Se você fez o curso anterior, já está familiarizado com isso aqui. Mas, se você não fez, não tem nenhum problema. Não é um requisito você ter feito o curso de Drift e Hive.

Nossas listas de compras têm ID, nome, observação, data de criação e data de atualização. E, cada uma delas guarda uma lista de produtos. E cada produto tem um ID, nome, categoria, se é por quilo ou não. Se está no carrinho, se está planejado, que é o "está comprado", preço, quantidade e observações.

Uma coisa bem importante agora: Como vamos trafegar essa informação para o nosso servidor que vai guardar as informações? Simples! Isso tudo vai ser transformado em um JSON (JavaScript Object Notation).

Então, ele é um JSON que vai estar lá no firebase, mas poderia ser em qualquer outro servidor. Que vai conter um map (mapa), um esquema de chave-valor. Que a chave maior de todas se chama listins. E esses listins, aí sim, têm uma lista onde cada um vai ter o ID do listin, o nome da feira, a observação, se foi criado e por aí vai, os elementos.

E dentro desse listin vai ter os produtos. Dentro desses "produtos" tem de fato os nossos produtos. É assim que vamos fazer essa comunicação.

Integrando o local_data_handler.dart ao projeto

Agora, vamos voltar para o projeto para mostrar, provavelmente, a coisa mais importante desse vídeo. Então, preste bem atenção. Se você veio do curso anterior, o que é natural, já que está na formação, apesar de um não estar necessariamente conectado com o outro só em projeto, você pode já estar com esse projeto do listin pronto na fase que estamos aqui.

Mas se for o caso, na atividade "Preparando o Ambiente", vai ter um arquivo bem especial, que é exatamente o _core > data > local_data_handler.dart. Você vai ver que esse arquivo não foi criado no curso anterior.

Se você acabou de chegar ao projeto, não se preocupe, esse arquivo já vai estar aqui. Mas caso você já esteja seguindo do curso anterior, peço para você baixar esse arquivo e colocar na pasta data, porque esse arquivo vai fazer a comunicação que precisamos com os pacotes de persistência de dados, o Drift e o Hive, para que não tenhamos que nos preocupar com isso nesse curso.

É a última vez que estamos falando de persistência de dados local, porque justamente precisamos pegar esses dados que estão salvos localmente, fazer uma transformação neles para poder enviar para a nuvem, e não é nosso objetivo no curso de Dio.

Basicamente, são dois métodos: o localDataToMap, que pega todas as informações locais, todos os listins e todos os produtos e transforma no Map. Se você quiser dar uma lida nele, pode ficar à vontade, mas não é nosso foco.

E o mapToLocalData faz exatamente o contrário, pega um Map que veio com todas as informações lá do servidor e salva no nosso banco de dados local da aplicação. Esse foi o detalhe mais importante.

A versão usada no curso

Mais uma coisa também muito importante, que é nossa versão. Qual é a versão que esse curso está rodando? Se digitarmos flutter --version no terminal, você vai ver que este curso está sendo gravado na versão 3.16.9 do Flutter e na versão 3.2.6 do Dart.

É bem importante que você mantenha as mesmas versões que nós para que não tenha nenhum problema.

O Flutter vive se atualizando, sempre há alguma diferença de código ou algo semelhante. E o mesmo se aplica para o pubspec.yaml. Dê uma boa olhada nas dependências que já tem instaladas, são várias para o listin chegar aonde já está e vamos também instalar o Dio logo na sequência.

Então, é bem interessante que você siga com uma versão igual a nossa. Caso não seja possível seguir as mesmas versões do pubspec.yaml e do Flutter e do Dart, dê uma boa olhada na atividade Preparando o Ambiente, que lá vamos ter algumas formas de mitigar possíveis problemas que podem acontecer caso você esteja usando uma versão mais atual.

Esses são os recados mais importantes que precisávamos dar e com isso dito, agora podemos ir para a implementação do Dio. Te vejo lá!

Entendendo DIO e HTTP - Instalando o Dio e configurando a tela

Já compreendemos o nosso projeto e qual desafio teremos para implementar nossas funcionalidades. Qual é o próximo passo? Começar a implementar essa conexão com o servidor.

Primeiro, precisamos instalar o DIO, o pacote que vai fazer essa comunicação com a API. E a segunda parte é criar um ambiente na nossa tela, no nosso Listin, que possa fazer essa comunicação com o servidor. Vamos aproveitar esse vídeo para fazer isso.

Então, já no nosso VSCode, vamos puxar o terminal para cima e vamos escrever flutter pub add dio. Vamos dar um Enter. Não tem problema esses pequenos erros que aparecem no terminal do VSCode. Mas, rodando esse código, você vai ver que ele já vai baixar a dependência, rodar o flutter pub get.

Mais uma vez, aquele detalhe com o versionamento. Vamos abrir nosso pubspec.yml no explorador e você vai ver que ele instalou o DIO na versão 5.4.1. É o ideal que você siga a nossa versão também.

Fechando o pubspec.yml, precisamos criar algum lugar nessa tela inicial para poder fazer a comunicação com o servidor.

Para fazer isso, vamos primeiro encontrar essa tela. Sabemos que ela está dentro da pasta listins. Vamos fechar a core, vamos abrir a listins > screens > home_screen.dart.

Vamos fechar o nosso explorador e um lugar que pode ficar bem legal de colocar é na própria appBar. Então, na linha 40, dentro da nossa appBar, vamos adicionar um actions. Esse actions nos permite colocar alguns botões ali no canto direito da appBar. Então, o que vamos adicionar é um PopupMenuButton, por enquanto. Porque é o botão que vai chamar esse Popup com vários outros botões.

O que precisamos passar aqui? Além desse itemBuilder que ele está pedindo, no começo desses parênteses vamos passar também um icon. Porque queremos definir nosso icon, queremos que ele use o padrão. E esse icon vai ser Icon(Icons.cloud), que vai dar uma ideia de nuvem, de comunicação com a nuvem.

No lugar desse itemBuilder que está dando erro, vamos apagar e vamos dar um Ctrl + Espaço. Ele já vai nos sugerir como ele quer essa função, não é? Então, vamos escolher a segunda opção (context) {}. E aqui podemos retornar uma lista.

Ele espera uma lista de quê? Ele espera uma lista de botões, de botões específicos, de itens. Então, esses itens vão ser PopupMenuItem.

Precisamos definir algumas coisas para esse PopupMenuItem. A primeira coisa é o valor dele. Então, vamos passar o valor, vamos chamar de save, por enquanto.

Cada valor vai definir o que acontece quando clicamos em um desses menus. Vamos definir o valor como SAVE. Você pode considerar isso como uma chave.

E o filho vai ser listTile. Porque queremos que ele tenha aquele comportamento de ícone, de um título. Falando nisso, vamos definir o ícone como leading. Vamos passar aqui um ícone, Icons.upload. E o título vai ser algo como Text("Salvar na nuvem"). Vamos colocar umas vírgulas para melhorar a visualização.

Isso cria um botão na appBar do emulador que pode ser acessando clicando no botão de ícone da nuvem na lateral superior direita. A ideia é fazer uma lista de botões, cada um com uma funcionalidade.

O código para os outros botões será muito parecido. Então vamos copiar toda a const PopupMenuItem e o que ela tem entre colchetes. Colaremos esse código duas vezes para editá-lo em seguida.

No segundo const PopupMenuItem, mudaremos o "SAVE" para "SYNC", de Icons.upload, mudaremos para Icons.download, para pegar o símbolo de download. Além disso, o texto "Salvar na nuvem" será substituído por "Sincronizar na nuvem".

Assim, um sobe para a nuvem e o outro sincroniza com as informações que estão na nuvem. Por fim, na linha 61, no terceiro PopupMenuItem colado, substituiremos o "SAVE" por "CLEAR", o Icons.upload por Icons.delete e o título será "Remover dados da nuvem".

Afinal, sempre que salvamos dados de pessoas usuárias na nuvem, é sempre muito importante permitir que elas removam, se assim desejarem, por uma questão de proteção de dados.

            itemBuilder: (context) {
              return [
                const PopupMenuItem(
                  value: "SAVE",
                  child: ListTile(
                    leading: Icon(Icons.upload),
                    title: Text("Salvar na nuvem"),
                  ),
                ),
                const PopupMenuItem(
                  value: "SYNC",
                  child: ListTile(
                    leading: Icon(Icons.download),
                    title: Text("Sincronizar da nuvem"),
                  ),
                ),
                const PopupMenuItem(
                  value: "CLEAR",
                  child: ListTile(
                    leading: Icon(Icons.delete),
                    title: Text("Remover dados da nuvem"),
                  ),
                ),
              ];
            },

Definidos os valores desses PopupMenuItem, precisamos fazer com que o PopupMenuButton esteja preparado para reagir quando um desses for clicado.

Para fazer isso, abriremos uma nova linha depois do icon, pressionaremos Ctrl + Espaço e procuraremos por onSelected. Ele nos dá uma função que tem um valor, que é justamente o valor selecionado, ou seja, clicado.

Então, já podemos testar se o valor for igual a "SAVE", faremos alguma coisa. Usamos o Alt + Shift + Seta para baixo para duplicar essa linha duas vezes. Se for "SYNC" será outra, e se for "CLEAR", outra.

E quais são as coisas que queremos fazer? Queremos chamar métodos. Não precisamos nos preocupar em implementá-los ainda, mas queremos chamá-los. Vamos ao menos declará-los no fim do código, depois de tudo o que já existe.

Criaremos um método chamado saveOnServer(), vamos defini-lo como assíncrono (async), pois as alterações serão todas assíncronas. Criaremos também um syncWithServer(), ou seja, sincronizar com o server. Por último, criaremos também um clearServerData. Todos não fazem nada por enquanto, mas já montamos a estrutura da tela.

  saveOnServer() async {}

  syncWithServer() async {}

  clearServerData() async {}

Voltando para as condicionais, quando for clicado em "SAVE", chamamos saveOnServer(), quando clicarmos em "SYNC", chamamos syncWithServer() e quando clicarmos em "CLEAR", chamamos clearServerData().

          PopupMenuButton(
            icon: const Icon(Icons.cloud),
            onSelected: (value) {
              if (value == "SAVE") {
                saveOnServer();
              }
              if (value == "SYNC") {
                syncWithServer();
              }
              if (value == "CLEAR") {
                clearServerData();
              }
            },

Agora instalamos o DIO e nossa aplicação já está preparada para ter ao menos um ambiente de interação com a pessoa usuária onde ela pode salvar, sincronizar e remover os dados da nuvem.

Ainda falta programarmos essa parte. É o que vamos fazer na sequência. Te vejo lá!

Sobre o curso Flutter: utilizando o Dio para realizar a comunicação com Web API

O curso Flutter: utilizando o Dio para realizar a comunicação com Web API possui 134 minutos de vídeos, em um total de 54 atividades. Gostou? Conheça nossos outros cursos de Flutter em Mobile, ou leia nossos artigos de Mobile.

Matricule-se e comece a estudar com a gente hoje! Conheça outros tópicos abordados durante o curso:

Aprenda Flutter acessando integralmente esse e outros cursos, comece hoje!

Conheça os Planos para Empresas