Middleware
- logging middleware
- json middleware
뭐 이런걸 만들었음
이를 nest에서도 사용할 수 있다.
Middleware에 Dependency Injection
Middleware 만들기
cli를 통해 만든다.
nest g middleware logger
import { Injectable, NestMiddleware } from '@nestjs/common';
@Injectable()
export class LoggerMiddleware implements NestMiddleware {
use(req: Request, res: Response, next: NextFunction) {
console.log(req.ip);
next();
}
}
그러면 위와 같이 생성이 되고 (ip를 찍을 수 있도록 코드 수정)
등록하려면 app.module.ts 파일에
export class AppModule{}
이였던 부분을
export class AppModule implements NestModule {
configure(consumer: MiddlewareConsumer) {
consumer.apply(LoggerMiddleware).forRoutes('cats');
}
}
와 같이 수정한다.
forRoutes('*') 를 쓸 경우 모든 부분을 다 돌 수 있는 것이다.
이렇게하고 요청을 보내면
로거 미들웨어를 돌아서 ip를 찍어주는 것을 볼 수 있다.
logger 를 사용하기
this.logger.log(`${req.ip} ${req.method}`, req.originalUrl);
위를 사용하면 로깅을 사용할 수 있는 것임
Exception and Filter
아무 엔드포인트나 들어가면 404 코드가 뜸.
이걸 서비스에서 사용할 때, 페이지로 띄우고 싶다거나
아니면 어떤 요청에서 에러가 있다고 할 때
throw new HttpException('api is broken', 401);
이런 식으로 필터 걸어줄 수 있는 것이다.
공식문서의 http exception 을 가져온다.
https://docs.nestjs.com/exception-filters
import {
ExceptionFilter,
Catch,
ArgumentsHost,
HttpException,
} from '@nestjs/common';
import { Request, Response } from 'express';
@Catch(HttpException)
export class HttpExceptionFilter implements ExceptionFilter {
catch(exception: HttpException, host: ArgumentsHost) {
const ctx = host.switchToHttp();
const response = ctx.getResponse<Response>();
const request = ctx.getRequest<Request>();
const status = exception.getStatus();
response.status(status).json({
statusCode: status,
timestamp: new Date().toISOString(),
path: request.url,
});
}
}
위의 코드를 보면 response, request 를 둘다 가져온다. statusCode와 timeStamp를 찍어준다.
Filter를 적용하는 방법
- decorator 방법
cats.controller.ts 파일에 아래와 같이 적용한다.
@Get()
@UseFilters(HttpExceptionFilter)
getAllCat() {
return 'all cat';
}
그러면 그 결과 아래와 같은 로그가 찍히는 것을 확인할 수 있다.
{
"success": false,
"timestamp": "2022-12-18T11:22:26.312Z",
"path": "/cats",
"error": "api broken"
}
이거를 Class 위에다가도 쓸 수 있다.
@UseFilters(HttpExceptionFilter)
export class CatsController {
constructor(private readonly catsService: CatsService) {}
...
}
위와 같이 사용
- global로 등록하는 방법
main.ts 에다가 적용한다.
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { HttpExceptionFilter } from './http-exception.filter';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
app.useGlobalFilters(new HttpExceptionFilter());
await app.listen(8000);
}
bootstrap();
useGlobalFilters() 를 사용하면 된다.
결론 Middleware를 거치고 Controller를 거치고 Service를 거친 후 Filter까지 거친다는 것을 알면 된다.
Pipes
넘어오는 파라미터의 type을 변환해줌.
@Get(':id')
getOneCat(@Param('id', ParseIntPipe) param) {
console.log(param);
console.log(typeof param);
return 'one cat';
}
위와 같이 코딩하면 원래 id 값으로 넘어오는 param의 type은 string 이였는데 int로 바꿔서 받을수 있게 된다.
근데 만약에 int로 바꿀 수 없는 abc 뭐 이런게 들어 왔다면 알아서 validation error를 보내준다.