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?

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:

“ servcode:

[ Http>], [servcode]

<✓Key <✓Valor
HttpRequest {url:"/api/dogs",…} HttpResponse" [] [ HttpResponse"“ [
HttpRequest {url:"/api/cães/name='bingo'",...} HttpRingo}"tespond name,"… >
HttpRe>" {/url>"“/urltd:”““/urlzz74zz74zz74zz74z67z67z67zv2z79zz74″ “/url>”““//urlzz74”.

Http> ”

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 .

Source link