HttpInterceptor é um dos recursos mais poderosos do Angular. Você pode usá-lo para simular um back-end para que possa testar aplicativos Angular facilmente, sem o incômodo de configurar um servidor.
Neste tutorial do HttpInterceptor, vamos demonstrar como usar o HttpInterceptors para armazenar em cache solicitações HTTP .
Abordaremos o seguinte:
- Por que armazenar solicitações HTTP em cache?
- Por que usar HttpInterceptor
- Usando HttpInterceptor em Angular
- Configurando o HttpInterceptor
- Por que você deve adotar o Angular
Por que armazenar solicitações HTTP em cache?
O cache de solicitações HTTP ajuda a otimizar seu aplicativo. Imagine solicitar um dado do servidor toda vez que uma solicitação é feita, mesmo que os dados nunca tenham mudado com o tempo. Isso afetaria o desempenho do seu aplicativo devido ao tempo que leva para processar os dados no servidor e enviá-los quando os dados nunca foram alterados em relação às solicitações anteriores.
Para remover o atraso no processamento dos dados no servidor quando eles não foram alterados, precisamos verificar se os dados no servidor foram alterados. Se os dados mudaram, processamos novos dados do servidor. Caso contrário, pulamos o processamento no servidor e enviamos os dados anteriores. Isso é chamado de cache .
Em HTTP, nem todas as solicitações são armazenadas em cache. As solicitações POST
, PUT
e DELETE
não são armazenadas em cache porque alteram os dados no servidor.
POST
e PUT
adicionam dados ao servidor enquanto DELETE
remove dados do servidor. Portanto, precisamos processá-los sempre que forem solicitados, sem armazená-los em cache.
Solicitações
GET
podem ser armazenadas em cache. Eles apenas obtêm dados do servidor sem alterá-los. Se nenhuma solicitação POST
, PUT
ou DELETE
ocorrer antes da próxima solicitação GET
, os dados do último GET não muda. Simplesmente retornamos os dados ou respostas anteriores sem atingir o servidor.
Os navegadores modernos têm um mecanismo integrado para armazenar em cache nossas solicitações HTTP. Mostraremos como fazer isso no Angular.
Por que usar HttpInterceptor?
HttpInterceptors
são serviços especiais no Angular. As solicitações HTTP são passadas por eles na cadeia antes que a solicitação real seja feita ao servidor.
Simplificando, HttpInterceptors
intercepta e manipula solicitações HTTP. Normalmente, os HttpInterceptors
chamam next.handle (thirtyReq)
para transformar as solicitações de saída antes de passá-las para o próximo interceptor na cadeia. Em casos raros, os interceptores lidam com as solicitações por conta própria, em vez de delegar ao restante da cadeia.
Usando HttpInterceptor em Angular
Criaremos nosso HttpInterceptor
para que sempre que colocarmos uma solicitação GET
, a solicitação passe pelos interceptores da cadeia. Nosso interceptor verificará a solicitação para determinar se ela foi armazenada em cache. Em caso afirmativo, ele retornará a resposta em cache. Caso contrário, ele passará a solicitação para o restante da cadeia para, eventualmente, fazer uma solicitação real do servidor. O interceptor observará a resposta quando receber a resposta e a armazenará em cache para que qualquer outra solicitação retorne a resposta em cache.
Também forneceremos uma maneira de redefinir o cache. Isso é ideal porque se os dados processados pela API GET foram alterados por POST
, PUT
, DELETE
desde a última solicitação, e nós’ainda estou retornando os dados em cache. Estaremos lidando com dados desatualizados e nosso aplicativo exibirá resultados incorretos.
Configurando HttpInterceptor
Todos os HttpInterceptors implementam a interface HttpInterceptor
:
interface de exportação HttpInterceptor { interceptar (req: HttpRequest, próximo: HttpHandler): Observável >; }
O método de interceptação é chamado com a solicitação req: HttpRequest
e o próximo HttpHandler
.
HttpHandler
s são responsáveis por chamar o método intercept
no próximo HttpInterceptor na cadeia e também passar no próximo HttpHandler
que irá chamar o próximo interceptor.
Para configurar nosso interceptor, CacheInterceptor
:
@Injectable () class CacheInterceptor implementa HttpInterceptor { cache privado: Map=new Map () interceptar (req: HttpRequest , próximo: HttpHandler): Observável > { if (req.method!=="GET") { retornar next.handle (req) } const cachedResponse: HttpResponse=this.cache.get (req) if (cachedResponse) { retorno de (cachedResponse.clone ()) }outro { retornar next.handle (req).pipe ( fazer (stateEvent=> { if (stateEvent instanceof HttpResponse) { this.cache.set (req, stateEvent.clone ()) } }) ).compartilhar() } } }
Como o método de solicitação não é uma solicitação GET, nós o passamos ao longo da cadeia-sem armazenamento em cache.
Se for um GET, obtemos a resposta em cache da instância do mapa cache
usando o método Map # get
passando o req
como chave. Estamos armazenando a solicitação HttpRequest
como uma chave e a resposta HttpResponse
como o valor na instância do mapa, cache
.
O mapa será estruturado assim:
<✓Key✓ | <✓Valor |
HttpRequest {url:"/api/dogs",…} |
HttpResponse" “ [ | ] [
HttpRequest {url:"/api/cães/name='bingo'",...} |
|
Uma chave é uma instância HttpRequest e seu valor correspondente é uma instância HttpResponse
. Usamos seus métodos get
e set
para recuperar e armazenar os HttpRequests
e HttpResponses
. Portanto, quando chamamos get
em cache
, sabemos que obteremos um HttpResponse
.
A resposta é armazenada em cachedResponse
. Verificamos para ter certeza de que não é nulo (ou seja, recebemos uma resposta). Em caso afirmativo, clonamos a resposta e a devolvemos.
Se não obtivermos uma resposta do cache, sabemos que a solicitação não foi armazenada em cache antes, então deixamos passar e ouvimos a resposta. Se encontrarmos um, o armazenamos em cache usando o método Map # set
. O req
se torna a chave e a resposta se torna o valor.
Precisamos observar os dados desatualizados ao armazenar em cache. Precisamos saber quando os dados foram alterados e fazer uma solicitação ao servidor para atualizar o cache.
Podemos usar métodos diferentes para conseguir isso. Podemos usar o cabeçalho If-Modfied-Since
, podemos definir nossa data de validade no cabeçalho HttpRequest
, ou podemos definir um sinalizador no cabeçalho para detectar quando fazer uma solicitação de servidor completa.
Vamos para a terceira opção.
Nota : Existem muitas maneiras de restaurar o cache; as opções listadas acima são apenas algumas que vêm à mente.
O truque aqui é adicionar um parâmetro à solicitação quando o usuário está fazendo uma solicitação, para que possamos testar o cabeçalho em nosso CacheInterceptor
e saber quando passá-lo para o servidor.
public fetchDogs (reset: boolean=false) { return this.httpClient.get ("api/dogs", new HttpHeaders ({reset})) }
O método fetchDogs
tem um parâmetro booleano reset
. Se o parâmetro reset
estiver definido como true
, o CacheInterceptor
deve fazer uma solicitação ao servidor. Ele define o parâmetro reset
no cabeçalho antes de fazer a solicitação. O cabeçalho contém a redefinição, assim:
reset | verdade ou resto | falso
O CacheInterceptor
deve verificar o parâmetro de redefinição no cabeçalho para determinar quando descansar o cache. Vamos adicioná-lo à nossa implementação CacheInterceptor
:
@Injectable () class CacheInterceptor implementa HttpInterceptor { cache privado: Map=new Map () interceptar (req: HttpRequest , próximo: HttpHandler): Observável > { if (req.method!=="GET") { retornar next.handle (req) } if (req.headers.get ("reset")) { this.cache.delete (req) } const cachedResponse: HttpResponse=this.cache.get (req) if (cachedResponse) { retorno de (cachedResponse.clone ()) }outro { retornar next.handle (req).pipe ( fazer (stateEvent=> { if (stateEvent instanceof HttpResponse) { this.cache.set (req, stateEvent.clone ()) } }) ).compartilhar() } } }
Solicitamos o parâmetro reset
nos cabeçalhos req. Se o parâmetro reset
for true
, excluímos o cache HttpRequest/HttpResponse
do cache
usando o mapa método #delete
. Então, com o cache excluído, uma solicitação do servidor é feita.
Por último, precisamos registrar nosso CacheInterceptor
no token de matriz HTTP_INTERCEPTROS
. Sem ele, nosso interceptor não estará na cadeia de interceptores e não podemos armazenar solicitações em cache.
@NgModule ({ ... provedores: { fornecer: HTTP_INTERCEPTORS, useClass: CacheInterceptor, multi: true } }) ...
Com isso, nosso CacheInterceptor
selecionará todas as solicitações HTTP feitas em nosso aplicativo Angular.
Por que você deve adotar o Angular
Os interceptores são muito úteis, principalmente porque reduzem drasticamente a enorme quantidade de código necessária para implementar o cache HTTP.
Por esse motivo, recomendo que você adote o Angular. React, Vue.js e Svelte não possuem esse recurso. Conseguir cache de HTTP e interceptar usando essas estruturas seria uma grande dor de cabeça.
A postagem Cache com HttpInterceptor em Angular apareceu primeiro em LogRocket Blog .