Olá! Gostaríamos de dar as boas-vindas a mais um curso de Flutter aqui na Alura.
Meu nome é William Bezerra, sou um homem pardo, de cabelo preto e barba preta, e serei o instrutor ao longo de toda esta jornada, na qual desenvolveremos o aplicativo Memorando.
Um aplicativo para gestão de tarefas domésticas utilizará o conceito e a aplicação do GraphQL para realizar diversas atividades e possibilitar a conexão entre um cliente GraphQL e um aplicativo Flutter. Com isso, conseguiremos criar atividades, listar atividades em uma listagem paginada com scroll infinito, semelhante ao que ocorre em aplicativos como Instagram e Twitter. Além disso, será possível interagir e alterar, por exemplo, marcando uma atividade como concluída.
Teremos também a questão das subscriptions, um conceito interessante do GraphQL, que permite ouvir interações em tempo real. Por exemplo, se outro usuário ou nós mesmos marcarmos uma atividade como concluída, a quantidade de atividades pendentes será reduzida. Da mesma forma, se alguém adicionar uma nova atividade, a quantidade de atividades pendentes aumentará automaticamente em tempo real.
Para acompanhar este curso, é importante já ter conhecimento básico sobre o funcionamento de APIs e chamadas de dados, para absorver o máximo de conteúdo. Nos encontramos na próxima aula.
TaskViewModel
Agora, vamos começar a implementar algumas funcionalidades no nosso aplicativo. Vamos criar uma classe TaskViewModel
que irá gerenciar o estado das tarefas e notificar a interface do usuário sobre as mudanças.
Primeiro, vamos definir a estrutura básica da classe TaskViewModel
que estende ChangeNotifier
. Isso nos permitirá usar o padrão de notificação para atualizar a interface do usuário quando o estado das tarefas mudar.
class TaskViewModel extends ChangeNotifier {
}
Dentro dessa classe, vamos implementar o método toggleTaskStatus
, que será responsável por alternar o status de uma tarefa entre concluída e não concluída. Inicialmente, vamos apenas definir a assinatura do método.
Future<void> toggleTaskStatus(Task task) async {
}
Em seguida, vamos adicionar o método updateTask
, que será usado para atualizar uma tarefa existente. Este método chamará um caso de uso (use case) que lida com a lógica de atualização da tarefa e, em seguida, chamará o método refresh
para notificar a interface do usuário sobre a mudança.
Future<void> updateTask(Task task) async {
await _updateTaskUseCase(task: task);
refresh();
}
O método _updateTaskUseCase
é responsável por realizar a operação de atualização da tarefa. Vamos garantir que ele seja chamado corretamente dentro do método updateTask
.
await _updateTaskUseCase(task: task);
Além disso, vamos implementar o método deleteTask
, que será responsável por excluir uma tarefa com base no seu ID. Assim como no método de atualização, ele chamará um caso de uso específico para a exclusão e, em seguida, atualizará a interface do usuário.
Future<void> deleteTask(int id) async {
await _deleteTaskUseCase(id);
refresh();
}
O método _deleteTaskUseCase
é chamado para realizar a exclusão da tarefa.
await _deleteTaskUseCase(id);
TaskViewModel
Com esses métodos, nossa classe TaskViewModel
está preparada para gerenciar as operações básicas de uma tarefa, como alternar o status, atualizar e excluir. Isso nos permitirá manipular as tarefas de forma eficiente e manter a interface do usuário sempre atualizada com o estado mais recente das tarefas.
Durante uma conversa com nosso parceiro, colega de quarto, cônjuge ou namorada, decidimos criar um aplicativo para gerenciar as tarefas diárias de nossa casa. Como desenvolvedores, vimos nisso uma oportunidade de ter controle sobre nossas tarefas e, ao mesmo tempo, adquirir experiência. Assim, nasceu o aplicativo chamado Memorando.
Com o Memorando, podemos criar novas tarefas, como "tirar o lixo", adicionar descrições, definir categorias, salvar essas informações, marcar tarefas como concluídas, editar detalhes e até apagar atividades. No entanto, percebemos que o aplicativo funcionava apenas localmente, o que significava que, ao fechar e reiniciar, perderíamos todos os dados. Precisávamos de um back-end para salvar e controlar os dados remotamente, permitindo que outras pessoas também pudessem usar o aplicativo.
Após estudar as alternativas para criar um banco de dados e configurar o back-end, estabelecemos alguns pré-requisitos: o aplicativo deveria funcionar offline e manter os dados mesmo sem internet, além de ser leve para não sobrecarregar o dispositivo com mais de 20 mil tarefas. Optamos por usar GraphQL, que nos oferece controle dos dados e um cliente próprio para cache, além de ser uma solução de low-code.
Encontramos o Hasura, uma ferramenta que nos permite criar e modelar dados automaticamente, gerando um back-end GraphQL para nossa aplicação. Com o Hasura configurado, temos uma estrutura onde a aba de data centraliza todos os dados, permitindo criar e gerenciar tabelas, como a tabela de tasks
.
Para integrar o back-end e acessar os dados, utilizamos o GraphQL. No Hasura, a aba de API nos dá acesso ao Playground, onde podemos estruturar e definir chamadas de GraphQL. Vamos começar criando uma query básica.
Primeiro, definimos uma query vazia:
query {
}
Em seguida, especificamos que queremos acessar as tasks
:
query {
tasks
}
Para obter detalhes específicos, como o título das tarefas, expandimos a query:
query {
tasks {
title
}
}
Podemos adicionar mais campos, como o ID das tarefas:
query {
tasks {
id
title
}
}
E, finalmente, incluímos o campo isCompleted
para verificar se a tarefa foi concluída:
query {
tasks {
id
title
isCompleted
}
}
Ao executar essas queries no Playground, recebemos um JSON com os dados solicitados. Essa é a essência do GraphQL: permitir que busquemos exatamente os dados de que precisamos. Na próxima etapa, veremos como integrar essa estrutura no Flutter, permitindo que nosso aplicativo Memorando se conecte ao back-end e funcione de forma completa e eficiente.
Agora que já entendemos como o GraphQL funciona com o Razor e conseguimos fazer toda a configuração do nosso back-end, precisamos configurar o Flutter para utilizar a ferramenta. Como faremos isso? Vamos começar utilizando um package específico para essa estrutura, chamado GraphQL Flutter.
Para adicionar o package, abriremos o terminal do VSCode e executaremos o seguinte comando:
flutter pub add graphql_flutter
Com isso, o package será adicionado. Este é um dos mais utilizados pela comunidade para essa configuração. Caso queiramos utilizar outro package que vimos, como um criado pela comunidade para usar com o Razor, podemos ficar à vontade. A ideia é que funcione de maneira semelhante, mas o GraphQL Flutter possui uma estrutura mais robusta para trabalhar com cache e outras funcionalidades, e é ele que utilizaremos ao longo do curso.
Após executar o comando, o package será adicionado. Vamos abrir o menu lateral do VSCode e acessar o arquivo pubspec.yaml
para verificar se está tudo correto. Dentro das dependências, o GraphQL Flutter versão 5.2.0 Beta deve estar adicionado:
graphql_flutter: ^5.2.0-beta.8
Com isso, iniciaremos a configuração da API. Vamos abrir a pasta "config" e criar um arquivo chamado api_client.dart
. Nele, criaremos uma classe ApiClient
, onde configuraremos uma função para criar nosso cliente GraphQL. A estrutura básica será a seguinte:
// Filename: api_client.dart
class ApiClient {
static GraphQLClient create() {
// Configurações serão adicionadas aqui
}
}
Dentro da função create
, definiremos o cliente com final client = GraphQLClient(...)
, e faremos as configurações de link e cache. Após isso, retornaremos o cliente:
static GraphQLClient create() {
final client = GraphQLClient(link: link, cache: cache);
return client;
}
Para o link, criaremos uma variável link
que será igual a HttpLink(...)
. Ele receberá como parâmetro uma URI, que é a string de acesso ao GraphQL. No caso do Razor, conseguiremos essa informação na aba do Razor, onde há um endpoint GraphQL. Copiaremos esse link e o colaremos no VSCode:
final httpLink = HttpLink('https://uncommon-maggot-51.hasura.app/v1/graphql');
Com isso, já temos o link configurado. Entretanto, se voltarmos ao Razor, ele possui uma chave de acesso, de autenticação, que é um token extenso necessário para garantir que o projeto tenha as credenciais necessárias para o acesso. Precisamos configurar essa chave dentro do link para que, ao conectar, ele passe o valor e possamos conectar diretamente.
Para isso, faremos a seguinte configuração no código, dentro do nosso client. Vamos criar outra variável, que será igual a um AuthLink
:
final authLink = AuthLink(
getToken: () => const String.fromEnvironment('HASURA_TOKEN'),
headerKey: 'x-hasura-admin-secret',
);
Como essa informação é sigilosa, não podemos inseri-la diretamente no código. Para isso, utilizaremos o DART DEFINE
, que é a configuração do DART para definir variáveis de ambiente dentro do projeto.
Com isso, temos os dois links, mas o authLink
ainda não está sendo utilizado. Vamos criar outra variável para concatenar os dois links, completando a configuração:
final link = authLink.concat(httpLink);
Precisamos configurar nosso cache para armazenar e controlar dados, conforme mencionado anteriormente. Vamos criar outra variável chamada cache
e inicializar o GraphQLCache
:
final cache = GraphQLCache();
Com isso, temos nosso client configurado. Agora, precisamos utilizá-lo para realizar o primeiro acesso diretamente no Razor, baixar os dados, obtê-los via API e exibi-los na nossa listagem. É exatamente isso que faremos na próxima etapa.
O curso Flutter: graphql e suporte offline possui 153 minutos de vídeos, em um total de 49 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:
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.