Nest.js

Nest.js Middleware logger

martinooo 2022. 12. 5. 19:24

๐Ÿคณ Nest.js ๋ฏธ๋“ค์›จ์–ด๋ž€?


๋ฏธ๋“ค์›จ์–ด๋Š” Route ํ•ธ๋“ค๋Ÿฌ ๋ณด๋‹ค ๋จผ์ € ํ˜ธ์ถœ๋˜๋Š” ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค. ๋ฏธ๋“ค ์›จ์–ด ๊ธฐ๋Šฅ์€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์š”์ฒญ-์‘๋‹ต ์ฃผ๊ธฐ์—์„œ ์š”์ฒญ ๋ฐ ์‘๋‹ต ๊ฐ์ฒด ์™€ ๋ฏธ๋“ค์›จ์–ด ๊ธฐ๋Šฅ์— ์•ก์„ธ์Šคํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Next() ๋‹ค์Œ ์ž‘์—…์œผ๋กœ ๋„˜๊ธด๋‹ค๋Š” ์˜๋ฏธ์ž…๋‹ˆ๋‹ค. 

Nest.js ๋ฏธ๋“ค์›จ์–ด๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ Express ๋ฏธ๋“ค์›จ์–ด์™€ ๋™์ผํ•˜๋‹ค.  

  • ๋ฏธ๋“ค์›จ์–ด ๊ธฐ๋Šฅ์€ ๋‹ค์Œ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
    • ๋ชจ๋“  ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค. 
    • ์š”์ฒญ ๋ฐ ์‘๋‹ต ๊ฐ์ฒด๋ฅผ ๋ณ€๊ฒฝํ•ฉ๋‹ˆ๋‹ค. 
    • ์š”์ฒญ-์‘๋‹ต ์ฃผ๊ธฐ๋ฅผ ์ข…๋ฃŒํ•ฉ๋‹ˆ๋‹ค. 
    • ์Šคํƒ์—์„œ ๋‹ค์Œ ๋ฏธ๋“ค์›จ์–ด ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค. 
    • ํ˜„์žฌ ๋ฏธ๋“ค์›จ์–ด ๊ธฐ๋Šฅ์ด ์š”์ฒญ-์‘๋‹ต ์ฃผ๊ธฐ๋ฅผ ์ข…๋ฃŒํ•˜์ง€ ์•Š์œผ๋ฉด Next() ๋‹ค์Œ ๋ฏธ๋“ค์›จ์–ด ๊ธฐ๋Šฅ์œผ๋กœ ์ œ์–ด๋ฅผ ์ „๋‹ฌํ•˜๋„๋ก ํ˜ธ์ถœํ•ด์•ผ ํ•œ๋‹ค. Next() ํ˜ธ์ถœํ•˜์ง€ ์•Š์„๊ฒฝ์šฐ ์š”์ฒญ์ด ์ค‘๋‹จ ๋ฉ๋‹ˆ๋‹ค. 

 

์ •๋ฆฌํ•˜๋ฉด: ๋ฏธ๋“ค์›จ์–ด๋Š” ํด๋ผ์ด์–ธํŠธ ์‚ฌ์ด๋“œ์—์„œ ์š”์ฒญํ•œ Http Request์—์„œ Router Handler๋กœ ๊ฐ€๊ธฐ ์ „์— ๊ธฐ๋Šฅ์„ ๊ณตํ†ตํ™” ํ•˜์—ฌ ์‚ฌ์šฉํ•˜๊ฑฐ๋‚˜ ์ฒ˜๋ฆฌํ•˜๊ฒŒ ํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ ๊ทธ ์ดํ›„ Next()๋ผ๋Š” ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•ด์„œ ๋‹ค์Œ ์ž‘์—…์ด ์ง„ํ–‰ ๋  ์ˆ˜ ์žˆ๊ฒŒ ํ•œ๋‹ค.


๐Ÿคณ Nest.js ์‹ค์Šต?


1. Root ๋””๋ ‰ํ† ๋ฆฌ์—์„œ middlewareํด๋”๋ฅผ ์ƒ์„ฑํ•˜๊ณ  logger.middleware.ts ํŒŒ์ผ์„ ์ƒ์„ฑํ•œ๋‹ค.

2. logger.middleware.ts์— logger ๊ตฌํ˜„ 

  • ๋ฏธ๋“ค์›จ์–ด๋Š” router๋ณด๋‹ค ๋จผ์ € ์‹คํ–‰์ด ๋œ๋‹ค. 
  • ๋ผ์šฐํ„ฐ ์‹œ์ž‘ํ• ๋•Œ ์š”์ฒญ์„ ๊ธฐ๋กํ•˜๊ณ , next()๋กœ ๋ผ์šฐํ„ฐ๋กœ ์—ฐ๊ฒฐ์„ํ•˜๊ณ  ๋๋‚˜๊ณ  ์‹คํ–‰ํ•˜๊ธฐ ์œ„ํ•ด์„œ res.on์„ ์‚ฌ์šฉํ–ˆ๋‹ค.
  • Next() ๋‹ค์Œ์œผ๋กœ ๋„˜์–ด๊ฐ€๊ธฐ์ „์— console.log ์š”์ฒญ ๋ฐ์ดํ„ฐ์— ๊ฐ’์„์„ ์„ค์ •ํ–ˆ๋‹ค.
import { Injectable, Logger, NestMiddleware } from "@nestjs/common";
import { NextFunction, Request, Response } from "express";

@Injectable()
export class LoggerMiddleware implements NestMiddleware{
    private logger = new Logger('HTTP');

    use(req: Request, res: Response, next: NextFunction): void{
        const { ip, method, originalUrl } = req;
        const userAgent = req.get('user-agent') || '';

        console.log({
            ip: ip,
            url : req.url,
            method : req.method,
            body: req.body,
        })
        res.on('finish', () => { 
            const { statusCode } = res;
            const contentLength = res.get('content-length');
            this.logger.log(
                `${method} ${originalUrl} ${statusCode} ${contentLength} - ${userAgent} ${ip}`,
            );
        });
        next();
    }
}

3. logger ์—ฐ๊ฒฐํ•˜๊ธฐ /src/app.module.ts 

  • app.module.ts ํ•˜๋‹จ์— logger ์—ฐ๊ฒฐํ•œ๋‹ค.
  • path: ์™€์ผ๋“œ ์นด๋“œ๋กœ ๋ชจ๋“  path ๊ฒฝ๋กœ์— middleware ์„ค์ •ํ–ˆ๋‹ค.
  • method: ๋ชจ๋“  ์š”์ฒญ method๋ฅผ middleware ์„ค์ •ํ–ˆ๋‹ค.
export class AppModule implements NestModule{
  configure(consumer: MiddlewareConsumer) {
    consumer
    .apply(LoggerMiddleware)
    .forRoutes({ 
      path : '*', 
      method: RequestMethod.ALL
    })
  }
}

๐Ÿคณ Implements, Injectable๋ฅผ ์•Œ์•„๋ณด์ž


logger ์…‹ํŒ…ํ•˜๋ฉด์„œ implements๋ฅผ ์‚ฌ์šฉํ•œ ์ด์œ ๋Š”?

๊ตณ์ด ์‚ฌ์šฉํ•˜์ง€ ์•Š์•„๋„ ์—๋Ÿฌ๋Š” ์—†๋‹ค!

ํ•˜์ง€๋งŒ ์‚ฌ์šฉํ•˜๋ฉด ๋‚ด๋ถ€ ๋กœ์ง์„ ๋ฐ˜๋“œ์‹œ ๊ตฌํ˜„ํ•ด์•ผ ํ•˜๋„๋ก ๊ฐ•์ œํ•˜๋ฉฐ ํ•จ์ˆ˜ ์ด๋ฆ„, ๋งค๊ฐœ๋ณ€์ˆ˜, ๋ฆฌํ„ด ๊ฐ’ ๋“ฑ์˜ ํƒ€์ž… ๊ฒ€์‚ฌ๋ฅผ ํ•ด์ค€๋‹ค.

ex) configrue๋ผ๋Š” ์˜คํƒ€ ๋ฐœ์ƒ์‹œ implements๋ฅผ ๋ถ™์ด์ง€ ์•Š์•˜๋‹ค๋ฉด ์—๋Ÿฌ๋ฅผ ๋ฐœ์ƒ์‹œํ‚ค์ง€ ์•Š์ง€๋งŒ ๋ถ™์˜€๋‹ค๋ฉด ์—๋Ÿฌ๋ฅผ ๋ฐœ์ƒ์‹œํ‚ค๊ธฐ ๋•Œ๋ฌธ์— ์‰ฝ๊ฒŒ ๊ณ ์น  ์ˆ˜ ์žˆ๋‹ค.

implements : ๋ถ€๋ชจ์˜ ํด๋ž˜์Šค์—์„œ ์ƒ์†์„ ๋‚ด๋ ค์ฃผ๋Š” ์—ญํ™œ์ด์ง€๋งŒ ์ด๊ฒƒ์€ ๋” ๊ณต๋ถ€๋ฅผ ํ•ด๋ด์•ผ๊ฒ ๋‹ค.


Nest.JS์—์„œ injectable์ด๋ž€?

@Injectable() //nest.js ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ.

injectable ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์œผ๋ฉด provider๋ผ๋Š” ํ˜•ํƒœ๋ฅผ ๋„๋Š”๋ฐ ๊ทธ๋Ÿฌ๊ฒŒ ๋˜๋ฉด ํ•ด๋‹น module์—์„œ providers์— ๋„ฃ์–ด์ค˜์•ผํ•œ๋‹ค.

๊ทธ๋Ÿฌ๋ฏ€๋กœ, nest.JS dependency injection๋Š” providers๋ฅผ ๋ณด๊ณ  controller์— service๋“ค์„ ๋„ฃ์–ด์ค๋‹ˆ๋‹ค.