Como obter dados da internet no Flutter usando HTTP

Como obter dados da internet no Flutter usando HTTP
Jhoisnáyra Vitória Rodrigues de Almeida
Jhoisnáyra Vitória Rodrigues de Almeida

Compartilhe

Introdução

Quando trabalhamos com desenvolvimento front-end (parte da aplicação com a qual o usuário interage e vê - em geral é a tela), seja ele mobile ou web, é comum que precisemos nos comunicar com o back-end (de onde vêm os dados, o que torna a aplicação funcional de fato - em geral, um banco de dados), e uma das primeiras comunicações que aprendemos é a obtenção de dados da internet.

Neste artigo, vamos aprender como obter dados da internet no Flutter utilizando a biblioteca HTTP, entendendo da requisição para a internet até a aplicação final exibindo os dados na tela para o usuário.

E o melhor de tudo: vamos aprender tudo isso na prática - com um projeto real! Essa aplicação obtém, da internet, uma lista de filmes (com título e imagem) e a mostra para o usuário. Veja:

GIF colorido. Aplicação de celular com uma barra superior na cor rosa e um texto “Filmes Studio Ghibli”. No corpo da aplicação, uma lista de filmes sendo mostrada.

Conhecimentos prévios

Para que aproveite bem o conteúdo deste artigo, é interessante que você domine algumas habilidades e técnicas em Flutter (aliás, temos cursos que ensinam esses conhecimentos aqui na Alura):

Banner promocional da Alura, com um design futurista em tons de azul, apresentando dois blocos de texto, no qual o bloco esquerdo tem os dizeres:

Entendendo nosso projeto: O aplicativo Filmes Studio Ghibli

Vamos utilizar um projeto prático para aprender a habilidade de obter dados da internet e mostrá-los em um aplicativo Flutter! Você pode acessar o projeto inicial neste link do GitHub.

Imagine que você precisa fazer um projeto de aplicativo Flutter com as seguintes características:

  1. A pessoa usuária consegue ver uma lista de filmes do Studio Ghibli;
  2. Essa lista é um tipo de dado disponível apenas de forma online, ou seja, o celular e o app precisam se conectar à internet e pegar esses dados para depois exibi-los na tela para a pessoa usuária.

Como podemos, então, fazer com que o app acesse esses dados disponíveis na internet (mais especificamente em um banco de dados)?

Infográfico que mostra o título “Como obter dados da internet” e o subtítulo com os dizeres “Queremos mostrar informações (dados) na tela de um aplicativo Flutter. Como fazer para pegar os dados que estão na internet? “ Abaixo, à esquerda, há o ícone de um celular, um ponto de interrogação no centro da imagem. Ao lado direito, há o símbolo de um banco de dados acompanhado dos dizeres “servidor ou banco de dados da internet”; logo acima do símbolo de servidor, há um ícone de filme acompanhado dos dizeres “As informações estão armazenadas em um servidor ou banco de dados.

Bom, precisamos seguir uma série de passos:

  1. Instalar o pacote HTTP;
  2. Usar o pacote HTTP para fazer uma requisição GET que obtém os dados dos filmes (disponíveis na internet);
  3. Converter os dados obtidos do tipo “JSON” em objetos;
  4. Mostrar os dados dos filmes.

Veremos cada um dessas etapas! A primeira envolve um tal de pacote HTTP - mas o que é isso?

Conhecendo o pacote HTTP

Imagem que mostra uma série de símbolos da internet conectados por linhas em um fundo azul escuro.

Para obter dados da internet (no nosso caso, informações sobre filmes do estúdio Ghibli), precisamos de um pacote HTTP que vai fazer a comunicação com a internet. Vamos ver isso com mais detalhes!

Em sua documentação, o Flutter oferece o pacote HTTP, que faz requisições HTTP que são mensagens enviadas do cliente para um servidor - o cliente pode ser um app, por exemplo.

Ou seja, a função do pacote HTTP é enviar “mensagens” para a internet e pedir os dados para um servidor. O nome técnico dessas mensagens/pedidos é requisições HTTP.

Sobre as requisições HTTP, essas mensagens enviadas para o servidor podem ser de vários tipos ou verbos, sendo os mais conhecidos:

  • GET: Usado para obter dados da internet (que podem ser mostrados na tela depois);
  • POST: Usado para enviar dados novos (para salvar uma informação, por exemplo);
  • PUT: Usado para substituir dados já existentes (que edita um dado já existente); e
  • DELETE: Usado para apagar dados.

Além disso, quando enviamos uma requisição (request, em inglês) ao servidor, vamos receber de volta uma resposta (response), e essa resposta pode conter o que esperávamos receber de volta ou, por exemplo, a informação de algum erro ocorrido.

Em geral, junto da resposta do servidor, vem um código chamado Status Code, e ele pode ser de diferentes valores:

  • Respostas informativas (100 a 199);
  • Respostas bem-sucedidas (200 a 299);
  • Mensagens de redirecionamento (300 a 399);
  • Respostas de erro do cliente (400 a 499);
  • Respostas de erro do servidor (500 a 599).

Quando obtemos sucesso na requisição (recebemos o que esperávamos), o valor do Status Code é 200!

Em Flutter, e com o pacote HTTP, não é diferente! Nós enviamos uma request e recebemos uma response.

E agora que você já sabe o que é o pacote HTTP, pode começar a praticar. Vamos lá?

Passo 1: Instalando o pacote

Para instalar o pacote HTTP em nosso projeto, vamos usar o seguinte comando no terminal:

flutter pub add http

Isso deve adicionar a seguinte linha no seu arquivo pubspec.yaml:

dependencies:
  HTTP: ^0.13.5

A versão utilizada durante a produção deste artigo é a ^0.13.5, mas pode ser que quando esteja lendo, já se tenha uma versão mais atualizada (mas para que funcione bem, exatamente como explico no artigo, é importante usar a mesma versão que utilizei). E se tiver interesse em conhecer mais sobre a biblioteca, acesse o site oficial.

Pronto, tudo instalado, e agora podemos pôr a mão no código!

Passo 2: Obtendo dados da Web com GET

Para começar a implementar a funcionalidade na nossa aplicação Filmes Studio Ghibli, vamos precisar da lista de filmes (dados que estão disponíveis apenas na internet).

Aprendemos que, para obter esses dados da internet em um projeto Flutter, precisamos de um pacote como o HTTP que se comunica com a internet e permite que a gente use um verbo do tipo GET que vai fazer uma solicitação a uma API (veremos o que é isso já já).

Em resumo, quando pegamos um dado da internet, o app se comunica com uma API (e não com o servidor/banco de dados diretamente).

Uma API, de maneira bem simples, pode ser vista como um meio de comunicação e integração entre o front-end e o back-end, como um telefone entre eles!

Infográfico com o título “Como obter dados da  internet” e o subtítulo “Para acessar os dados do servidor, precisamos do pacote HTTP e de uma API. Ao lado esquerdo, há um celular cuja tela contém os ícones do Flutter e do pacote HTTP. No centro da imagem, há o ícone de uma nuvem que representa uma API. Ao lado direito, há dois ícones: um de servidor e outro de um filme.

No caso, vamos simular uma API com um arquivo hospedado no GitHub com uma lista de filmes que queremos exibir. Usaremos, então, uma Fake API que contém os dados dos filmes que queremos exibir.

Faz sentido?

A seguir, precisamos acessar essa API simulada. Para fazer isso, em nosso projeto, vamos criar um arquivo com uma função chamada getFilmes. Essa função vai fazer uma requisição GET, ou seja, um pedido dos dados (como se o app dissesse para a API “Oi, me vê os dados aí, por favor!”).

Vejamos como fica a função getFilmes:

import 'package:http/http.dart' as http;

Future<void> getFilmes() async {

 final response = await http.get(Uri.parse(
      'https://raw.githubusercontent.com/alura-cursos/obtendo_dados_com_flutter_http/main/filmes.json'));

print(response.body);
}

Chamaremos o arquivo acima de repository.dart.

Com apenas uma função, fazemos a requisição GET para obter os dados! Veja uma representação desse processo:

Infográfico que apresenta o título “Como obter dados da internet” e o subtítulo “O pacote HTTP faz um pedido (requisição GET) para a API. Ao lado esquerdo da tela, há a imagem de um celular que contém o ícone do pacote HTTP. Do dispositivo parte uma flecha, acompanhada da informação “requisição GET”, que incide sobre o ícone de API. Do lado do ícone API, no lado direito do infográfico, há os ícones de um servidor e um filme que representa os dados.

Como vemos na imagem, o dispositivo com o projeto Flutter, graças ao pacote HTTP, faz uma requisição GET - no caso, a função getFilmes.

Vamos entender os detalhes da implementação dessa função:

1) Para começar, importamos o pacote http:

import 'package:http/http.dart' as http;

2) Depois, veja que adotamos uma função assíncrona - visto que estamos lidando com informações da internet e esses dados podem demorar para chegar - e sem retorno - pois, por enquanto, queremos apenas imprimir a resposta no terminal. Daí a necessidade de usar as palavras Future<void>, async e await;

3) Como a requisição nos retorna uma resposta, um valor, criamos uma variável chamada response, que irá guardar esse resultado recebido; e

4) Na requisição, usamos http.get(), cujo conteúdo dentro desse comando é exatamente um URI (identificador de recurso), daí a necessidade transformarmos o nosso link nisso, com a instrução uri.parse.

Assim, a requisição é enviada para a API (que faz a ligação entre o dispositivo/aplicativo e o servidor). Por sua vez, a API pede os dados para o servidor:

Infográfico que representa a requisição GET que sai do dispositivo, passa pela API e chega em um banco de dados back-end.

Em seguida, o banco responde a API:

Infográfico que representa a conexão de um dispositivo com uma API e um servidor e mostra o banco de dados enviando dados à API.

Por último, a API faz a resposta para o dispositivo, enviando o dado recebido em formato JSON:

Infográfico com o título “Como obter dados da internet e o subtítulo “A API envia, para o dispositivo, a resposta (response) com os dados em formato JSON. O Infográfico representa a resposta da API para o dispositivo com dados JSON.

Ufa! Finalmente! E o resultado da nossa requisição GET é a seguinte lista, em formato JSON, com nomes e imagens de filmes:

Print que mostra o resultado da requisição com a lista de filmes e os dados estruturados, que são “nome” e “imagem”.

Se você quiser conferir, o código segue abaixo:

[
  {
    "nome": "A Viagem de Chihiro",
    "imagem": "HTTPs://br.web.img3.acsta.net/pictures/210/527/21052756_20131024195513383.jpg"
  },
  {
    "nome": "Ponyo",
    "imagem": "HTTPs://m.media-amazon.com/images/I/61ry7KsRfIS._AC_SL1000_.jpg"
  },  
  {
    "nome": "Meu Amigo Totoro",
    "imagem": "HTTPs://i0.wp.com/studioghibli.com.br/wp-content/uploads/2020/04/meu-amigo-totoro-dvd-vers%C3%A1til.jpg"
  },  
  {
    "nome": "Princesa Mononoke",
    "imagem": "HTTPs://i0.wp.com/studioghibli.com.br/wp-content/uploads/2020/04/Princesa-Mononoke-DVD-capa-vers%C3%A1til.jpg"
  },  
  {
    "nome": "Castelo Animado",
    "imagem": "HTTPs://capas.nyc3.cdn.digitaloceanspaces.com/650-5000245618508.jpg"
  },  
  {
    "nome": "A Viagem de Chihiro",
    "imagem": "HTTPs://br.web.img3.acsta.net/pictures/210/527/21052756_20131024195513383.jpg"
  },
  {
    "nome": "As Memórias de Marnie",
    "imagem": "HTTPs://www.itaucinemas.com.br/_img/_filmes/1859_capa.jpg"
  }
]

Entendendo os dados que recebemos

Você pode estar se perguntando o tipo de informação que recebemos da API simulada e o conteúdo exato dela, pois falamos de um tal de JSON. Vamos entender tudo isso!

Como dito anteriormente, estamos usando um arquivo no GitHub (para simular uma API), que está em um formato específico, bastante utilizado na internet quando trabalhamos com APIs: o JSON.

O JSON é um formato leve, utilizado na internet para troca de dados entre diferentes sistemas. No Flutter, vamos precisar converter esses dados em objetos para que possamos exibir em nossa aplicação.

Infográfico que mostra a conversão de dados do tipo JSON em dados do tipo objeto. O infográfico apresenta o título: “Como obter dados da internet” e o subtítulo “Conversão de dados”. A seguir, há três frases. A primeira frase diz “os dados da API e servidor na internet chegam em formato JSON; a segunda, diz que “os dados JSON são convertidos em dados do tipo objeto que podem ser lidos pelo código Flutter; a última frase diz que “para simplificar, pense que é como uma tradução de uma língua (inglês) para outra (português).

Passo 3: Convertendo dados em objetos

Ao recebermos dados em formato de JSON, é necessário convertê-los em um model (já veremos o que é isso com detalhes), ou seja, um modelo de representação desses dados. Em nosso código, estamos recebendo filmes com nomes e imagens, e podemos criar o seguinte model:

class Filme {
  String nome;
  String imagem;

  Filme({
    required this.nome,
    required this.imagem,
  });

  Filme.fromJson(Map<String, dynamic> json)
      : nome = json['nome'].toString(),
        imagem = json['imagem'].toString();
}

Chamaremos o arquivo acima de filme.dart.

Este model nada mais é do que uma classe Filme, com os atributos recebidos no JSON (nome e imagem), e estamos usando dois construtores:

  • Um construtor comum que recebe duas Strings (nome e imagem); e

  • Um construtor nomeado e de redirecionamento, chamado fromJson (“do json”, em português) que recebe um Map chamado json - é esse construtor de redirecionamento que vai fazer a conversão dos dados do tipo JSON (que obtivemos da internet) para um objeto no Flutter.

Se quiser saber mais sobre o construtor nomeado, de redirecionamento e diversos outros tipos, recomendo a leitura do artigo Construtores no Dart: conhecendo tipos de construtores e como usá-los.

Agora que temos o model e o construtor que vai realizar a conversão (pense como uma “tradução” de um tipo de dado para outro), precisamos aplicar o model que criamos.

Vamos lá?

Aplicando o model que criamos

Para converter o arquivo JSON que recebemos em uma lista de objetos do tipo Filme, faremos da seguinte forma no arquivo repository.dart:

import 'package:http/http.dart' as http;
import 'dart:convert';
import '../models/filme.dart';

Future<List<Filme>> getFilmes() async {
  final response = await http.get(Uri.parse(
    'https://raw.githubusercontent.com/alura-cursos/obtendo_dados_com_flutter_http/main/filmes.json'));

  final json = jsonDecode(response.body);

  return List<Filme>.from(json.map((elemento) {
      return Filme.fromJson(elemento);
  })); 
}

Entendendo melhor o que alteramos na nossa função getFilmes:

1) Importamos, agora, a biblioteca dart:convert para utilizarmos o jsonDecode, além de importarmos o arquivo filme.dart, que contém o model de Filme:

import 'dart:convert';
import '../models/filme.dart';

2) Agora, invés de usar um Future<void> (sem retornar nada), vamos ter uma função Future<List<Filme>>, pois vamos retornar uma lista de objetos do tipo Filme:

Future<List<Filme>> getFilmes() async {
//…
}

3) Guardamos, em uma variável chamada json, a conversão do JSON em um objeto:

final json = jsonDecode(response.body);

4) Retornamos uma lista (List) com objetos do tipo Filme, realizando um map de cada elemento do objeto JSON, transformando um a um em objetos Filme:

  return List<Filme>.from(json.map((elemento) {
    return Filme.fromJson(elemento);
  }));

Legal! Agora que concluímos nossa função getFilmes, podemos utilizá-la para exibir o resultado para o usuário. Ou seja, o app já converte o JSON recebido da internet em uma lista de objetos do tipo Filme.

Tratando exceções na aplicação

Se você tiver testado o código anterior, pode ter percebido que, caso o link esteja incorreto, teremos uma exceção, ou seja, um erro que ocorreu enquanto o aplicativo estava executando. Essa exceção acontece pois há um erro na requisição que fizemos e não recebemos nenhum dado, portanto, precisamos tratá-la de alguma forma, e é isso que vamos fazer!

Para tratar, precisamos utilizar um condicional if-else que verifique se a requisição ocorreu com sucesso ou não. Podemos usar o response.statusCode neste caso, pois o valor dele vai indicar sucesso (se for 200) e algo diferente (se for um valor diferente de 200). Veja:

  if (response.statusCode == 200) {
/…
  } else {
/…
  }

E implementando essa verificação no nosso código, ficaria da seguinte maneira:

import 'package:http/http.dart' as http;
import 'dart:convert';
import '../models/filme.dart';

Future<List<Filme>> getFilmes() async {
  final response = await http.get(Uri.parse(
      'https://raw.githubusercontent.com/alura-cursos/obtendo_dados_com_flutter_http/main/filmes.json'));

  if (response.statusCode == 200) {
    final json = jsonDecode(response.body);
    return List<Filme>.from(json.map((elemento) {
      return Filme.fromJson(elemento);
    }));
  } else {
    return Future.error("Ops! Um erro ocorreu.");
  }
}

Em que:

  1. Verificamos se ocorreu tudo certo (se response.statusCode é igual a 200); e
  2. Caso tenha ocorrido tudo certo, retornamos a lista de filmes, como vimos anteriormente;
  3. Caso algo de errado tenha acontecido e não tenhamos dados, retornamos um objeto Future com um erro e a seguinte mensagem: “Ops! Um erro ocorreu”.

Tudo certo! Conseguimos colocar, dentro do dispositivo, os dados dos filmes do Studio Ghibli e cuidamos para que nenhuma exceção prejudique seu funcionamento. Bora mostrá-los na tela?

Passo 4: Exibindo resultados na tela

Para exibir os filmes na tela, vamos criar um novo arquivo chamado home.dart, no qual vamos criar um Widget do tipo Stateful chamado Home, ou seja, um Widget mutável, que possui estado.

Se quiser relembrar o que é um Widget Stateful, recomendo a leitura do artigo Flutter - Qual é a diferença entre stateless e stateful widget?

E escreveremos o seguinte código dentro de _HomeState:

class _HomeState extends State<Home> {
  Future<List<Filme>>? futureFilmes;

  @override
  void initState() {
    futureFilmes = getFilmes();
    super.initState();
  }
//…
}

Vamos entender os detalhes do que fizemos!

1) Estamos criando uma lista de filmes chamada futureFilmes, e ela é nullable, pois começa sem um valor;

Future<List<Filme>>? futureFilmes;

2) O initState é um método de Widgets Stateful que é chamado quando iniciamos uma tela, e estamos inicializando dentro dele a lista futureFilmes, usando a nossa função getFilmes:

  @override
  void initState() {
    futureFilmes = getFilmes();
    super.initState();
  }

Temos uma lista de objetos do tipo Filme, a futureFilmes, podemos agora utilizá-la e mostrar ao usuário o resultado na tela. Assim, usaremos o FutureBuilder, uma classe de Widget que utiliza o resultado de um Future para construir a si mesmo:

FutureBuilder(
        future: futureFilmes,
        builder: (context, snapshot) {
          if (snapshot.hasData) {
            final filmes = snapshot.data as List<Filme>;
            return ListaFilmes(filmes: filmes);
          } else if (snapshot.hasError) {
            return Center(
              child: Text(
                snapshot.error.toString(),
                style: const TextStyle(
                  fontSize: 16,
                ),
              ),
            );
          }
          return const Center(
            child: CircularProgressIndicator(),
          );
        },
      ),

Entendendo melhor o que fizemos:

  1. Estamos usando o FutureBuilder, e dentro dele temos:
    • 1.1. O future: que é a nossa lista futureFilmes;
    • 1.2. O builder que retorna (constrói) o Widget;
  2. Em builder temos uma função que recebe context e snapshot, em que o snapshot é o que nos interessa, pois ele é o conteúdo que recebemos;
  3. Por fim, verificamos se há algum dado (snapshot.hasData) ou se há algum erro (snapshot.hasError);
    • 3.1. Se houver dados, passamos eles por parâmetro para um Widget personalizado que eu construí;
    • 3.2. Se tiver havido um erro, mostramos a mensagem contida na variável snapshot.error (que nesse caso é ”Ops! Um erro ocorreu.”);
    • 3.3. E caso esteja carregando, mostramos um indicador de progresso circular.

E o código completo da nossa página fica da seguinte maneira:

import 'package:flutter/material.dart';
import '../components/lista_filmes.dart';
import '../models/filme.dart';
import '../repositories/repository.dart';

class Home extends StatefulWidget {
  const Home({Key? key}) : super(key: key);

  @override
  State<Home> createState() => _HomeState();
}

class _HomeState extends State<Home> {
  Future<List<Filme>>? futureFilmes;

  @override
  void initState() {
    futureFilmes = getFilmes();
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("Filmes Studio Ghibli"),
        centerTitle: true,
      ),
      body: FutureBuilder(
        future: futureFilmes,
        builder: (context, snapshot) {
          if (snapshot.hasData) {
            final filmes = snapshot.data as List<Filme>;
            return ListaFilmes(filmes: filmes);
          } else if (snapshot.hasError) {
            return Center(
              child: Text(
                snapshot.error.toString(),
                style: const TextStyle(
                  fontSize: 16,
                ),
              ),
            );
          }
          return const Center(
            child: CircularProgressIndicator(),
          );
        },
      ),
    );
  }
}

Acima o nosso arquivo home.dart completo.

Perfeito! Agora temos a nossa aplicação final, recebendo dados da internet, convertendo-os e mostrando para o usuário. Abaixo você pode conferir o resultado final que obtemos:

GIF colorido. Aplicação de celular com uma barra superior na cor rosa e um texto “Filmes Studio Ghibli”. No corpo da aplicação, uma lista de filmes sendo mostrada.

Concluímos nossa tarefa! Agora, se tiver curiosidade, você pode entender melhor como o projeto Filmes Studio Ghibli está organizado!

Estrutura do projeto e Widgets criados

Vamos ver a árvore de widgets do nosso projeto completo? Como você pode ver, utilizamos outros Widgets:

Imagem com a árvore de Widgets gerada pelo aplicativo no Flutter.

Na imagem acima, vemos a árvore do aplicativo, em que podemos observar que temos um Scaffold que contém um FutureBuilder, que, por sua vez, exibe um Widget chamado ListaFilmes (criado por mim). O ListaFilmes contém um GridView que mostra uma lista de Widgets CardFilme (também criado por mim). Repare que, a partir do CardFilme, a estrutura da árvore se repete, pois se trata de uma lista que repete o mesmo widget de cartão que apresenta cada filme.

E, além dos códigos que demonstrei aqui, utilizei de mais dois arquivos, os quais deixo para você - os Widgets ListaFilmes e CardFilme:

Arquivo lista_filmes.dart:

import 'package:flutter/material.dart';

import '../models/filme.dart';
import 'card_filme.dart';

class ListaFilmes extends StatelessWidget {
  const ListaFilmes({
    Key? key,
    required this.filmes,
  }) : super(key: key);

  final List<Filme> filmes;

  @override
  Widget build(BuildContext context) {
    return GridView.builder(
      padding: const EdgeInsets.all(16),
      gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
        crossAxisCount: 2,
        crossAxisSpacing: 12,
        mainAxisSpacing: 10,
        childAspectRatio: 3 / 4,
      ),
      itemCount: filmes.length,
      itemBuilder: ((context, index) {
        final filme = filmes[index];
        return CardFilme(
          nome: filme.nome,
          imagem: filme.imagem,
        );
      }),
    );
  }
}

Arquivo card_filme.dart:

import 'package:flutter/material.dart';

class CardFilme extends StatelessWidget {
  final String nome;
  final String imagem;

  const CardFilme({
    Key? key,
    required this.nome,
    required this.imagem,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        Expanded(
          child: Container(
            decoration: BoxDecoration(
                borderRadius: BorderRadius.circular(20),
                image: DecorationImage(
                  fit: BoxFit.cover,
                  image: NetworkImage(imagem),
                ),
                boxShadow: const [
                  BoxShadow(
                    color: Colors.blueGrey,
                    blurRadius: 4,
                    offset: Offset(0, 2),
                  )
                ]),
          ),
        ),
        const SizedBox(height: 8.0),
        Text(
          nome,
          style: const TextStyle(
            fontSize: 16,
            fontWeight: FontWeight.w500,
          ),
        ),
      ],
    );
  }
}

Veja também como ficou a estrutura do projeto:

├── lib
│   ├── components
│   │     └── card_filme.dart
│   │      └── lista_filmes.dart
│   ├── models
│   │   └── filme.dart
│   ├── repositories
│   │   └──repository.dart
│   ├── screens
│   │   └──home.dart
│   └── main.dart

E se quiser ver a aplicação completa, baixar e testar, deixo também o repositório do projeto no GitHub.

Conclusão

Meus parabéns por ter concluído a leitura!

Agora você já deve ser capaz de obter dados da internet utilizando o pacote HTTP de Flutter, além de exibi-los para a pessoa usuária da aplicação.

Vimos todo o fluxo de requisição e resposta para obter dados da internet, do dispositivo até o servidor e, também, passando pela API.

No nosso caso, usamos uma API simulada com um arquivo do Github, pois APIs na internet podem variar e mudar ao longo do tempo e, assim, garantimos que você possa praticar as técnicas ensinadas neste artigo sem se preocupar se a API funciona ou foi desativada.

Abaixo, deixamos um infográfico que resume bem todo o processo de requisição e resposta para obter dados da internet:

Imagem que representa como é o processo de requisição de dados da internet em Flutter, por meio do pacote HTTP.

Se quiser se aprofundar ainda mais no assunto, recomendo os cursos Flutter com WebAPI: integrando sua aplicação e Flutter com Web API: evoluindo na integração da aplicação, ambos da nossa formação Flutter.

Até a próxima e bons estudos!

GIF colorido, Animação do Studio Ghibli, personagem de cabelo marrom, vestes cor de rosa e está acenando.
Jhoisnáyra Vitória Rodrigues de Almeida
Jhoisnáyra Vitória Rodrigues de Almeida

Scuba Team Mobile (com foco em Flutter). Estudante de Ciência da Computação na UFPI, pesquisadora da área de Internet das Coisas e formada em Eletrônica pelo IFPI.

Veja outros artigos sobre Mobile