Dio: o que é e recursos do cliente HTTP para Flutter

Autor: IT Sectr Publicado: 2026-03-07 Tempo de leitura: 8 min

Dio é um poderoso cliente HTTP para Dart e Flutter, criado pelo engenheiro chinês Wenda Wang. A biblioteca fornece uma API avançada com suporte a interceptadores, FormData, upload de arquivos e cancelamento de requisições. De acordo com pub.dev, 2025, Dio é o cliente HTTP mais popular no ecossistema Flutter com mais de 8 mil estrelas no GitHub.

Principais pontos

  • Dio — um poderoso cliente HTTP para Dart e Flutter com interceptadores e transformadores
  • Interceptadores — um mecanismo para interceptar requisições, respostas e erros para registro e autorização
  • FormData — suporte nativo a multipart/form-data para upload de arquivos
  • Cancelamento de requisições — CancelToken permite interromper requisições em execução a qualquer momento
  • Transformadores — transformação personalizada de dados antes do envio e após o recebimento

O que é Dio?

Dio é uma poderosa biblioteca cliente HTTP para a linguagem Dart, mais amplamente usada em aplicações Flutter. Dio fornece uma API rica com suporte a interceptadores, configuração global, transformadores, FormData, upload de arquivos e gerenciamento flexível de timeouts, tornando-se a principal escolha para comunicação de rede na comunidade Flutter.

A biblioteca foi criada por Wenda Wang em 2018 como alternativa ao HttpClient nativo do dart:io, que não possuía muitos recursos modernos: configuração unificada para todas as requisições, interceptadores e serialização automática. Em 2025, Dio superou em popularidade o pacote http da equipe Dart, ocupando o primeiro lugar entre os clientes HTTP no ecossistema Flutter de acordo com o pub.dev.

Dio suporta três adaptadores: DartNativeAdapter (padrão no Android, iOS, Desktop), BrowserAdapter (na Web) e IOAdapter. O adaptador é selecionado automaticamente dependendo da plataforma. Dio também fornece uma interface unificada para todas as plataformas Flutter — Android, iOS, Web, macOS, Windows e Linux.

Como o Dio funciona

A arquitetura do Dio é construída em uma cadeia de manipuladores. Cada requisição passa por uma sequência de interceptadores que podem modificar a requisição (InterceptorsWrapper.onRequest), a resposta (onResponse) ou tratar um erro (onError). Após os interceptadores, a requisição vai para os transformadores (Transformer), que transformam os dados antes do envio.

Uma instância do Dio é configurada através de um objeto BaseOptions contendo a URL base, cabeçalhos padrão, timeouts, tipo de resposta (JSON, stream, plain), parâmetros de consulta e formato de dados. Essas configurações se aplicam a todas as requisições, mas podem ser substituídas em uma requisição específica. BaseOptions fornece um ponto único de configuração para toda a aplicação, simplificando alterações de endpoint ou adição de cabeçalhos globais.

Cada requisição no Dio retorna Response<T>, onde T é o tipo de dado após o processamento dos transformadores. Por padrão, o Dio converte automaticamente respostas JSON em Map<String, dynamic>. Para respostas tipadas, o Dio é usado junto com pacotes de serialização: json_serializable, freezed ou built_value. A Response contém data, headers, statusCode, requestOptions e dados extras.

Configuração global do Dio

A configuração básica é criada através de Dio(BaseOptions). É possível definir um baseUrl para todas as requisições, connectTimeout e receiveTimeout, cabeçalhos content-type e accept, bem como queryParameters. Todos esses parâmetros se aplicam a cada requisição, eliminando duplicação de código e centralizando o gerenciamento das configurações de rede.

Dio suporta dois modos de serialização: JSON por padrão (responseType: ResponseType.json) e streaming (ResponseType.stream). No modo stream, Response.data retorna um ResponseBody que pode ser lido em partes. Isso é conveniente para arquivos grandes onde carregar tudo na memória é indesejável. O modo plain retorna uma string bruta sem análise JSON automática.

Interceptadores do Dio

Os interceptadores são o mecanismo chave do Dio para interceptar e modificar requisições, respostas e erros. Eles substituem completamente o Interceptor do OkHttp e os plugins do Ktor, mas com uma API específica do Dart e suporte assíncrono via Future. Os interceptadores podem ser adicionados tanto na configuração global do Dio quanto para requisições individuais.

Método do interceptadorPropósitoExemplo de uso
onRequestModificar requisição antes de enviarAdicionar token de autorização
onResponseTratar resposta bem-sucedidaConverter data em objetos DTO
onErrorTratar erro de requisiçãoRepetição automática em 503

LogInterceptor

O LogInterceptor integrado registra cada requisição: método, URL, cabeçalhos, corpo e tempo de execução. Ele tem dois modos: compacto (uma linha por requisição) e completo (informação completa com corpo). O LogInterceptor é especialmente útil durante o desenvolvimento, mas é recomendado desativá-lo em builds de release através de imports condicionais ou uma flag global.

Interceptadores personalizados são criados através da classe InterceptorsWrapper. É possível sobrescrever um, dois ou os três métodos (onRequest, onResponse, onError). O Dio executa os interceptadores estritamente na ordem em que são adicionados à lista de interceptadores. Se um interceptador não chamar handler.next(), a cadeia é interrompida e a resposta ou erro não chega à aplicação.

Para autenticação no Dio, usa-se um interceptador que adiciona um token Bearer ao cabeçalho Authorization. Se o servidor retornar 401, o interceptador em onError tenta renovar o token através de uma requisição de refresh e repete a requisição original com o novo token. Este padrão é chamado de token refresh interceptor e é implementado através de DioException verificando response?.statusCode == 401.

Dio fornece suporte integrado para lógica de repetição através do pacote dio_smart_retry ou de um RetryInterceptor personalizado. A repetição é importante para aplicações móveis: quando a conexão é perdida por 2-3 segundos, o Dio lança uma DioException com tipo connectionTimeout ou connectionError. O RetryInterceptor captura essa exceção e repete a requisição até 3 vezes com backoff exponencial (1s, 2s, 4s), melhorando a confiabilidade da aplicação em condições de rede instáveis.

Exemplos de código Dio em Dart

Vejamos uma requisição GET básica com Dio. Uma instância é criada com BaseOptions, definindo a URL base e os timeouts. A requisição é executada através do método get(), retornando uma Response com dados no formato Map.

dart
final dio = Dio(BaseOptions(
    baseUrl: 'https://api.github.com',
    connectTimeout: Duration(seconds: 15),
    receiveTimeout: Duration(seconds: 15),
    headers: {
        'Accept': 'application/vnd.github.v3+json',
    },
))

final response = await dio.get('/users/octocat')
print(response.data['login'])

Para uma requisição POST com corpo JSON, um objeto Map ou um DTO personalizado é passado. O Dio serializa automaticamente o Map para JSON através de jsonEncode. Para DTOs tipados, usa-se a opção queryParameters, o campo data ou um Transformer personalizado.

dart
final data = {
    'name': 'my-project',
    'description': 'Created via Dio',
    'private': false,
}

final response = await dio.post(
    '/user/repos',
    data: data,
    options: Options(
        contentType: ContentType.json.value,
    ),
)

print(response.data['id'])

Adicionando um interceptador de autorização

Um interceptador personalizado adiciona um token Bearer a cada requisição. O método onRequest é acionado antes do envio, modificando os cabeçalhos. Em uma resposta 401, o interceptador pode renovar o token e repetir a requisição através do método dio.fetch(requestOptions).

dart
class AuthInterceptor extends InterceptorsWrapper {
    final String token

    AuthInterceptor(this.token)

    @override
    void onRequest(
        RequestOptions options,
        RequestInterceptorHandler handler,
    ) {
        options.headers['Authorization'] = 'Bearer $token'
        handler.next(options)
    }
}

dio.interceptors.add(AuthInterceptor('ghp_abc123'))

Upload e download de arquivos com Dio

Dio simplifica o upload de arquivos através de FormData. Para enviar um arquivo, um MultipartFile é criado a partir de File, Bytes ou AssetBundle. O FormData define automaticamente o cabeçalho multipart/form-data com o limite e codificação corretos. O Dio suporta progresso de upload através de onSendProgress.

Para download de arquivos, usa-se o método download(), que salva o fluxo de dados diretamente em um arquivo. O Dio suporta retomada de downloads interrompidos através do cabeçalho Range, o que é especialmente útil para arquivos grandes. O progresso do download é rastreado através de onReceiveProgress, permitindo exibir uma barra de progresso na interface do usuário.

dart
final formData = FormData.fromMap({
    'file': await MultipartFile.fromFile(
        '/path/to/photo.jpg',
        filename: 'photo.jpg',
    ),
    'description': 'Profile photo',
})

await dio.post(
    '/upload',
    data: formData,
    onSendProgress: (sent, total) {
        final progress = sent / total * 100
        print('Upload: $progress%')
    },
)

// Download de arquivo
await dio.download(
    'https://example.com/file.zip',
    '/storage/emulated/0/Download/file.zip',
    onReceiveProgress: (received, total) {
        print('Download: ${received / total * 100}%')
    },
)

Erros comuns ao trabalhar com Dio

Tratamento incorreto de erros é o problema mais comum. O Dio lança uma DioException (antigo DioError) para qualquer problema: falta de rede, timeout, erros HTTP 4xx/5xx. Muitos desenvolvedores capturam apenas a Exception genérica, perdendo informações sobre o tipo de erro e a capacidade de tratá-lo especificamente. Use DioException.type para determinar a causa da falha.

Ignorar CancelToken leva a vazamentos de requisições. Se um usuário sair de uma tela enquanto uma requisição ainda está em execução, o Dio desperdiça recursos e pode tentar atualizar um State destruído. Crie sempre um CancelToken para cada requisição e cancele-o em dispose(). O CancelToken gera uma DioException com tipo cancel, que deve ser tratada adequadamente.

Falta de lógica de repetição para falhas temporárias. Em dispositivos móveis, a rede frequentemente fica indisponível por um breve período. Implemente um interceptador com repetição automática de requisição em caso de timeout ou resposta 503/502. Use o RetryInterceptor do pacote dio_smart_retry ou escreva um interceptador personalizado com backoff exponencial entre as tentativas.

Perguntas frequentes

Como o Dio difere do pacote http do Dart?

Dio fornece interceptadores, configuração global BaseOptions, FormData, progresso de upload e CancelToken. O pacote http da equipe Dart é minimalista, sem interceptadores ou configuração global. Dio é usado em projetos grandes, enquanto http é usado para scripts simples.

Como serializar JSON no Dio?

Por padrão, o Dio converte JSON para Map usando jsonDecode. Para serialização tipada, use os pacotes json_serializable ou freezed. Crie um interceptador personalizado que converta response.data em DTO através de fromJson() no onResponse.

Como cancelar uma requisição no Dio?

Crie um CancelToken e passe-o nas opções da requisição. Chamar token.cancel() interrompe a requisição e lança uma DioException com tipo cancel. O CancelToken suporta o cancelamento de múltiplas requisições simultaneamente, o que é conveniente para cancelar todas as requisições ao sair de uma tela.

O Dio funciona em todas as plataformas Flutter?

Sim, o Dio funciona em todas as seis plataformas Flutter: Android, iOS, Web, macOS, Windows e Linux. Cada plataforma usa um cliente HTTP adaptativo: DartNativeAdapter (plataformas nativas) e BrowserAdapter (Web). Uma API unificada para todas as plataformas é uma vantagem chave do Dio em projetos Flutter.

Como o Dio lida com cookies?

O Dio não gerencia cookies automaticamente. Para suporte a cookies, use o pacote dio_cookie_manager junto com cookie_jar. O CookieManager intercepta os cabeçalhos Set-Cookie e Cookie e salva os cookies no PersistCookieJar para envio automático em requisições subsequentes ao mesmo domínio.

Resumo

  • Dio — o cliente HTTP mais popular no Flutter com interceptadores e transformadores
  • Interceptadores onRequest, onResponse e onError modificam requisições e respostas
  • FormData e MultipartFile simplificam o upload de arquivos para o servidor
  • CancelToken cancela requisições corretamente para evitar vazamentos de memória
  • BaseOptions centraliza a configuração de URL, cabeçalhos e timeouts
  • DioException contém o tipo de erro para tratamento detalhado de falhas
  • Progresso onSendProgress e onReceiveProgress exibem o estado dos uploads

Vamos desenvolver um aplicativo móvel chave na mão

A IT Sectr cria aplicativos para iOS e Android para startups e empresas desde 2017. Nós vamos aconselhá-lo e propor a melhor solução.

Discutir o projeto

Leia também