javascript - Nestjs registrar objeto de datos de respuesta
Quiero registrar las solicitudes entrantes y las respuestas salientes en NestJs. Tomé información de aquí Logging request/response in Nest.js y de la documentación NestJs Aspect Interception.
Sería increíble lograr esto sin usar paquetes externos, así que preferiría mucho una solución nativa de "Nest".
Para el registro de solicitudes, actualmente utilizo este código
@Injectable()
export class RequestInterceptor implements NestInterceptor {
private logger: Logger = new Logger(RequestInterceptor.name);
intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
const {
originalUrl,
method,
params,
query,
body,
} = context.switchToHttp().getRequest();
this.logger.log({
originalUrl,
method,
params,
query,
body,
});
return next.handle();
}
}
Esto registraría el siguiente resultado para GET /users
También quiero registrar la respuesta saliente. Actualmente uso este interceptor
@Injectable()
export class ResponseInterceptor implements NestInterceptor {
private logger: Logger = new Logger(ResponseInterceptor.name);
intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
const { statusCode } = context.switchToHttp().getResponse();
return next.handle().pipe(
tap(() =>
this.logger.log({
statusCode,
}),
),
);
}
}
Esto registraría el siguiente resultado para GET /users
pero ¿cómo puedo acceder a los datos que fueron enviados de vuelta al cliente?
Respuesta #1
Primero, sugeriría combinar estos en un solo registrador, solo para que toda la lógica de registro esté en un lugar.
En segundo lugar, para obtener los datos que se envían de vuelta al cliente, en tu función tap necesitas agregar un parámetro a la función, usualmente lo llamamos data, para que puedas saber qué se está enviando de vuelta. Esto está un poco oculto por Nest, ya que no está realmente claro sobre qué está trabajando el observable, pero al final, algo así termina funcionando para ti:
@Injectable()
export class AspectLogger implements NestInterceptor {
intercept(context: ExecutionContext, next: CallHandler) {
const req = context.switchToHttp().getRequest();
const { statusCode } = context.switchToHttp().getResponse();
const { originalUrl, method, params, query, body } = req;
console.log({
originalUrl,
method,
params,
query,
body,
});
return next.handle().pipe(
tap((data) =>
console.log({
statusCode,
data,
})
)
);
}
}
Esto también funcionará si decides descomponerlo de nuevo en sus dos interceptores separados, pero tener uno solo puede facilitar la determinación del tiempo de llamada también.

