Experts in Angular

HTTP ClientConfigurando HttpClient no Angular
Imagine o HttpClient como um mensageiro ágil e confiável

Configurando HttpClient no Angular

A maioria das aplicações web modernas precisa trocar dados com servidores, seja para baixar ou enviar informações, ou para acessar serviços que residem no lado do servidor. Para facilitar essa troca, o Angular oferece uma poderosa ferramenta: o HttpClient, um serviço que simplifica a realização de requisições HTTP.

Imagine o HttpClient como um mensageiro ágil e confiável, capaz de transportar informações entre sua aplicação Angular e o mundo dos servidores. Com ele, você pode solicitar dados, enviar formulários, interagir com APIs e muito mais. Mas antes de enviar nosso mensageiro em sua jornada, precisamos prepará-lo e equipá-lo com as ferramentas certas.

Fornecendo o HttpClient Através da Injeção de Dependências: A Preparação do Mensageiro

No Angular, a injeção de dependências é uma prática fundamental, que garante que nossos componentes e serviços recebam as ferramentas de que precisam para funcionar corretamente. Para utilizar o HttpClient, precisamos “injetá-lo” em nossos componentes, assim como um mecânico habilidoso equipa um carro de corrida com as peças necessárias.

A maneira mais comum de fornecer o HttpClient é através da função auxiliar provideHttpClient.

Fornecendo HttpClient Através da Injeção de Dependência

No Angular, o HttpClient é fornecido usando a função auxiliar provideHttpClient. Esta função é tipicamente incluída nos provedores da aplicação dentro do arquivo app.config.ts. Esta configuração garante que o HttpClient esteja disponível em toda a aplicação através do mecanismo de injeção de dependência do Angular.

Veja como você pode fornecer o HttpClient na configuração da sua aplicação:

// app.config.ts
import { ApplicationConfig } from '@angular/core';
import { provideHttpClient } from '@angular/common/http';

export const appConfig: ApplicationConfig = {
  providers: [
    provideHttpClient(),
  ]
};

Se sua aplicação utiliza o conceito de módulos (NgModule), você pode incluir o provideHttpClient na lista de provedores do módulo principal da sua aplicação, geralmente chamado de AppModule:

// app.module.ts
import { NgModule } from '@angular/core';
import { provideHttpClient } from '@angular/common/http';

@NgModule({
  providers: [
    provideHttpClient(),
  ],
  // ... outras configurações da aplicação
})
export class AppModule {}

Uma vez que o HttpClient está fornecido, você pode injetá-lo em seus componentes, serviços ou outras classes como uma dependência. Aqui está um exemplo de um serviço que usa o HttpClient para fazer requisições HTTP:

// config.service.ts
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';

@Injectable({ providedIn: 'root' })
export class ConfigService {
  constructor(private http: HttpClient) {
    // Este serviço agora pode fazer requisições HTTP via `this.http`.
  }
}

Ao configurar o HttpClient desta forma, o Angular garante que ele esteja disponível onde quer que você precise fazer requisições HTTP, promovendo uma arquitetura limpa e modular.

Agora que nosso mensageiro HttpClient está devidamente preparado, podemos equipá-lo com recursos adicionais para lidar com diferentes situações e desafios que encontraremos em sua jornada.

Equipando o HttpClient: Configurando Recursos Adicionais para a Jornada

Assim como um aventureiro experiente equipa-se com diferentes ferramentas para enfrentar os desafios de uma jornada, podemos equipar o HttpClient com recursos opcionais para lidar com diferentes situações e aprimorar sua funcionalidade. A função provideHttpClient aceita uma lista de configurações opcionais, permitindo que você personalize o comportamento do cliente HTTP.

withFetch: Utilizando a API fetch para Requisições Modernas

Por padrão, o HttpClient utiliza a API XMLHttpRequest para realizar requisições. Embora seja amplamente suportada, essa API possui algumas limitações em ambientes específicos. A configuração withFetch permite que você alterne para a API fetch, uma alternativa mais moderna e flexível.

Imagine a API fetch como um veículo off-road, capaz de navegar por terrenos que o XMLHttpRequest não consegue alcançar. Ela oferece recursos como streaming de dados e melhor suporte para requisições assíncronas. Para habilitar o uso da API fetch, basta adicionar a configuração withFetch ao provideHttpClient:

// app.config.ts
import { ApplicationConfig } from '@angular/core';
import { provideHttpClient, withFetch } from '@angular/common/http';

export const appConfig: ApplicationConfig = {
  providers: [
    provideHttpClient(
      withFetch(),
    ),
  ]
};

Por padrão, o HttpClient usa a API XMLHttpRequest para fazer requisições. A funcionalidade withFetch troca o cliente para usar a API fetch em vez disso.

A API fetch é mais moderna e está disponível em alguns ambientes onde o XMLHttpRequest não é suportado. No entanto, ela tem algumas limitações, como não produzir eventos de progresso de upload.

withInterceptors: Interceptando e Modificando Requisições

Interceptores são como agentes secretos que atuam nos bastidores, interceptando e modificando requisições HTTP antes que elas sejam enviadas ao servidor, ou antes que as respostas sejam processadas pela sua aplicação. Imagine que você precisa adicionar um cabeçalho de autenticação a todas as requisições, ou registrar o tempo de resposta de cada requisição. Os interceptores permitem que você realize essas tarefas de forma centralizada e eficiente.

A configuração withInterceptors permite que você registre uma lista de funções interceptoras, que serão executadas em ordem para cada requisição. Para saber mais sobre interceptores e como utilizá-los, consulte o guia de interceptores do Angular.

// app.config.ts
import { ApplicationConfig } from '@angular/core';
import { provideHttpClient, withInterceptors } from '@angular/common/http';

export const appConfig: ApplicationConfig = {
  providers: [
    provideHttpClient(
      withInterceptors(
        // Adicione seus interceptores aqui
      ),
    ),
  ]
};

Os interceptores permitem que você inspecione e transforme as requisições e respostas do HttpClient. Eles são úteis para adicionar cabeçalhos de autenticação, fazer logging, manipular erros, entre outras tarefas.

Ao equipar o HttpClient com a configuração withInterceptors, você adiciona uma camada extra de flexibilidade e controle sobre suas requisições HTTP, permitindo que você personalize o comportamento do cliente de acordo com as necessidades da sua aplicação.

withInterceptorsFromDi(): Integrando Interceptores Baseados em Injeção de Dependência (DI)

Em versões anteriores do Angular, os interceptores eram implementados como classes e fornecidos através do mecanismo de injeção de dependência (DI). A configuração withInterceptorsFromDi permite que você continue utilizando esses interceptores legados em sua aplicação.

// app.config.ts
import { ApplicationConfig } from '@angular/core';
import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http';

export const appConfig: ApplicationConfig = {
  providers: [
    provideHttpClient(
      withInterceptorsFromDi(),
    ),
  ]
};
É importante ressaltar que os interceptores funcionais, configurados através do <strong>withInterceptors</strong>, oferecem uma ordem de execução mais previsível e são recomendados em detrimento dos interceptores baseados em DI.

withRequestsMadeViaParent(): Compartilhando Requisições com o HttpClient do Injector Pai

Por padrão, ao configurar o HttpClient em um injetor específico, essa configuração substitui qualquer configuração existente no injetor pai. No entanto, em algumas situações, você pode desejar que as requisições passem pelos interceptores do injetor atual e também pelos interceptores do injetor pai.

A configuração withRequestsMadeViaParent permite que você alcance esse comportamento. Ao habilitá-la, o HttpClient configurado no injetor atual passará as requisições para o HttpClient do injetor pai, após elas terem sido processadas pelos interceptores locais. Imagine que você tem um módulo de autenticação que adiciona um interceptor para incluir um token de acesso em todas as requisições. Ao utilizar o withRequestsMadeViaParent, você garante que esse interceptor seja executado, mas também permite que outros interceptores configurados em níveis superiores da aplicação sejam aplicados.

// app.config.ts
import { ApplicationConfig } from '@angular/core';
import { provideHttpClient, withRequestsMadeViaParent } from '@angular/common/http';

export const appConfig: ApplicationConfig = {
  providers: [
    provideHttpClient(
      withRequestsMadeViaParent(),
    ),
  ]
};

Atenção: Para utilizar essa configuração, é crucial que exista uma instância do HttpClient configurada em um injetor acima do injetor atual. Caso contrário, você receberá um erro em tempo de execução ao tentar utilizar o withRequestsMadeViaParent.

withJsonpSupport(): Habilitando o Suporte a JSONP para Requisições Cross-Domain

Em cenários onde a política de mesma origem impede o acesso direto a recursos em domínios diferentes, o JSONP (JSON with Padding) oferece uma alternativa para carregar dados de forma segura. A configuração withJsonpSupport habilita o método .jsonp() no HttpClient, permitindo que você realize requisições GET utilizando a convenção JSONP.

Imagine o JSONP como um túnel secreto que permite a troca de informações entre domínios que, de outra forma, seriam inacessíveis. Ele funciona envolvendo a resposta JSON em uma função de callback, que é executada no contexto da página que originou a requisição.

// app.config.ts
import { ApplicationConfig } from '@angular/core';
import { provideHttpClient, withJsonpSupport } from '@angular/common/http';

export const appConfig: ApplicationConfig = {
  providers: [
    provideHttpClient(
      withJsonpSupport(),
    ),
  ]
};

Dica: Sempre que possível, prefira utilizar o CORS (Cross-Origin Resource Sharing) para realizar requisições cross-domain, pois ele oferece um mecanismo mais robusto e seguro.

withXsrfConfiguration(): Customizando a Proteção Contra XSRF

O XSRF (Cross-Site Request Forgery) é um tipo de ataque que explora a confiança de um site em seus usuários, induzindo-os a executar ações indesejadas. O Angular oferece proteção integrada contra XSRF, mas em algumas situações, você pode precisar personalizar essa funcionalidade.

A configuração withXsrfConfiguration permite que você ajuste os detalhes da proteção XSRF, como o nome do cabeçalho e do cookie utilizados para armazenar o token de proteção. Para obter mais informações sobre segurança e XSRF, consulte o guia de segurança do Angular.

// app.config.ts
import { ApplicationConfig } from '@angular/core';
import { provideHttpClient, withXsrfConfiguration } from '@angular/common/http';

export const appConfig: ApplicationConfig = {
  providers: [
    provideHttpClient(
      withXsrfConfiguration({
        cookieName: 'My-XSRF-TOKEN', // Nome do cookie XSRF
        headerName: 'My-XSRF-HEADER'  // Nome do cabeçalho XSRF
      }),
    ),
  ]
};

withNoXsrfProtection(): Desativando a Proteção XSRF

Em alguns casos específicos, você pode precisar desativar a proteção XSRF do HttpClient. Por exemplo, se sua aplicação se comunica apenas com APIs que não são vulneráveis a ataques XSRF, ou se você implementou um mecanismo de proteção personalizado em outro nível da sua aplicação.

A configuração withNoXsrfProtection permite que você desative completamente a funcionalidade de proteção XSRF do HttpClient. No entanto, é importante ressaltar que essa opção deve ser utilizada com cautela, pois pode expor sua aplicação a riscos de segurança.

// app.config.ts
import { ApplicationConfig } from '@angular/core';
import { provideHttpClient, withNoXsrfProtection } from '@angular/common/http';

export const appConfig: ApplicationConfig = {
  providers: [
    provideHttpClient(
      withNoXsrfProtection(),
    ),
  ]
};

Atenção: Desativar a proteção XSRF deve ser considerado apenas em situações onde você tem certeza de que sua aplicação não está vulnerável a ataques desse tipo. Consulte o guia de segurança do Angular para obter mais informações sobre XSRF e como proteger sua aplicação.

Configuração Baseada em HttpClientModule: Uma Abordagem Alternativa

Em algumas aplicações, a configuração do HttpClient pode ser realizada utilizando uma API mais antiga, baseada em módulos (NgModule). Essa abordagem, embora menos comum em projetos modernos, ainda pode ser encontrada em aplicações legadas ou em casos específicos.

A tabela a seguir relaciona os módulos disponíveis em @angular/common/http com as funções de configuração equivalentes do provideHttpClient:

NgModuleEquivalente em provideHttpClient()
HttpClientModuleprovideHttpClient(withInterceptorsFromDi())
HttpClientJsonpModuleprovideHttpClient(withJsonpSupport())
HttpClientXsrfModulewithXsrfConfiguration(...) ou withNoXsrfProtection() (dependendo das opções)

Atenção ao Usar HttpClientModule em Múltiplos Injetores:

Quando o HttpClientModule está presente em múltiplos injetores, o comportamento dos interceptores pode se tornar imprevisível e depender da ordem exata das opções e dos provedores/importações. Recomenda-se utilizar o provideHttpClient em configurações com múltiplos injetores, pois ele oferece um comportamento mais estável e previsível. Consulte a funcionalidade withRequestsMadeViaParent para obter mais detalhes sobre como compartilhar requisições entre injetores.

Ao configurar o HttpClient utilizando tanto a abordagem tradicional baseada em NgModules quanto a moderna utilizando provideHttpClient, você obtém uma flexibilidade completa para atender às necessidades específicas da sua aplicação Angular. Compreender ambas as abordagens permite que você escolha a melhor estratégia de acordo com a arquitetura do seu projeto e os requisitos de segurança e funcionalidade.

Resumo

A comunicação com serviços de backend é um componente essencial no desenvolvimento de aplicações web modernas, e o Angular fornece uma solução poderosa e flexível através do HttpClient. Nesta primeira parte da nossa série “Uma Jornada com o HttpClient do Angular”, exploramos as bases para configurar e usar o HttpClient em suas aplicações.

Iniciamos discutindo como configurar o HttpClient através da injeção de dependência, usando a função provideHttpClient. Demonstramos como essa abordagem permite um setup limpo e eficiente, garantindo que o HttpClient esteja disponível em toda a aplicação.

Em seguida, mergulhamos nas funcionalidades avançadas de configuração do HttpClient. Abordamos o uso do withFetch, que alterna a API de requisição para fetch, oferecendo uma alternativa moderna ao XMLHttpRequest. Exploramos a configuração de interceptores, tanto com withInterceptors para uma ordenação mais previsível, quanto com withInterceptorsFromDi para manter compatibilidade com o estilo antigo de interceptores baseados em classes.

Discutimos também a funcionalidade withRequestsMadeViaParent, que permite a passagem de requisições através dos injetores pais, oferecendo uma forma de manter uma cadeia de interceptores em múltiplos níveis de injetores. Além disso, cobrimos a inclusão do suporte a JSONP com withJsonpSupport e a personalização da proteção XSRF com withXsrfConfiguration.

Finalizamos a discussão das funcionalidades avançadas abordando como desabilitar a proteção XSRF com withNoXsrfProtection, destacando a importância de entender os riscos envolvidos e garantir que outras medidas de segurança estejam em vigor.

Para complementar, revisamos a configuração baseada em NgModules, que embora seja uma abordagem mais antiga, ainda é amplamente utilizada. Comparamos as equivalências entre os NgModules tradicionais e as novas funções de configuração, fornecendo uma compreensão completa de como migrar ou combinar as duas abordagens.

Esperamos que este guia seja uma referência valiosa para você e que ele inspire confiança no uso das funcionalidades do HttpClient.

Na próxima parte desta série, continuaremos a explorar outras funcionalidades avançadas do HttpClient, mergulhando ainda mais nas capacidades desta poderosa ferramenta. Fique atento para mais insights e práticas recomendadas que irão elevar suas habilidades no desenvolvimento de aplicações Angular.