RxJS e Intercepotres
RxJS é uma biblioteca de programação reativa baseada no padrão Observer, versão JavaScript do ReactiveX. Oferece operadores para manipulação de fluxos de dados assíncronos como eventos de UI, requisições de rede e temporizadores. Seu núcleo utiliza Observables para representar fluxos de dados, com operadores para transformação e combinação de valores.
Criação de Projeto e Interceptor
nest new projeto-interceptor -p npm
nest g interceptor tempo --flat --no-spec
import { CallHandler, ExecutionContext, Injectable, NestInterceptor } from '@nestjs/common';
import { Observable, tap } from 'rxjs';
@Injectable()
export class TempoInterceptor implements NestInterceptor {
intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
const inicio = Date.now();
return next.handle().pipe(
tap(() => console.log(`Execução: ${Date.now() - inicio}ms`))
);
}
}
@Controller()
export class AppController {
@Get()
@UseInterceptors(TempoInterceptor)
endpointRaiz() {
return this.appService.obterMensagem();
}
}
Operador Map
import { map } from 'rxjs';
@Injectable()
export class FormatarInterceptor implements NestInterceptor {
intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
return next.handle().pipe(
map(dados => ({
status: 200,
mensagem: 'sucesso',
dados
}))
);
}
}
Operador Tap
import { tap } from 'rxjs';
@Injectable()
export class RegistroInterceptor implements NestInterceptor {
constructor(private servico: AppService) {}
private logger = new Logger(RegistroInterceptor.name);
intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
return next.handle().pipe(
tap((dados) => {
this.servico.atualizarCache();
this.logger.log(`Registro: ${JSON.stringify(dados)}`);
})
);
}
}
Operador CatchError
import { catchError, throwError } from 'rxjs';
@Injectable()
export class ErroInterceptor implements NestInterceptor {
private logger = new Logger(ErroInterceptor.name);
intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
return next.handle().pipe(
catchError(erro => {
this.logger.error(erro.mensagem, erro.rastro);
return throwError(() => erro);
})
);
}
}
Operador Timeout
import { timeout, catchError } from 'rxjs';
@Injectable()
export class LimiteTempoInterceptor implements NestInterceptor {
intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
return next.handle().pipe(
timeout(4000),
catchError(erro => {
if (erro.name === 'TimeoutError') {
return throwError(() => new RequestTimeoutException());
}
return throwError(() => erro);
})
);
}
}
Intercepter Global
// main.ts
app.useGlobalInterceptors(new TempoInterceptor());
// app.module.ts
providers: [
{
provide: APP_INTERCEPTOR,
useClass: TempoInterceptor
}
]