[NestJS] 7. express에 싱글톤 패턴 적용 시키기, router에 서비스 적용시키기

주수호·2022년 5월 15일
0

singleton pattern

객체 인스턴스가 오직 한개만을 생성하게 하는 패턴을 말합니다.

ex) 클래스로 단 하나의 객체만을 생성하고 이를 사용함. 추후 메모리 낭비를 방지하고, 참조하기 쉽다고 합니다.

import * as express from "express";
import { ServerResponse } from "http";
import catsRouter from "./cats/cats.route";

class Server {
  public app: express.Application;

  constructor() {
    const app: express.Application = express();
    this.app = app;
  }

  private setRoute() {
    this.app.use(catsRouter);
  }

  private setMiddleware() {
    //middleware
    this.app.use((req, res, next) => {
      //next는 다음라우터로 넘어가는 함수
      console.log(req.rawHeaders[1]);
      console.log("this is logging middleware");
      next();
    });

    // json middleware
    this.app.use(express.json());

    this.setRoute;

    // 404 middleware
    this.app.use((req, res, next) => {
      console.log("this is error middleware");
      res.send({ error: "404 not found error" });
    });
  }

  public listen() {
    this.setMiddleware;
    this.app.listen(8000, () => {
      console.log("server is on.........");
    });
  }
}

function init() {
  const server = new Server(); //이렇게 싱글톤으로 고유의 객체를 생성하는 것이 가능해 집니다.
  server.listen();
}

init();

하나의 큰 Server라는 클래스를 만들고, constructor를 통해 생성한 express객체를 기준으로 하여, 지금 것 작성했던 middleware와 router들을 한 클래스에 모두 병합하였습니다.

그리고 이것을 init한번으로 호출하게끔 만들어져 있는거죠.

router를 service로 처리하기

router에 몰려있던 비즈니스 로직들을 service라는 파일로 분할하여 처리합니다. 이렇게 되면 유지보수가 훨씬 쉬워집니다.

import { Cat, CatType } from "./cats.model";
import { Request, Response } from "express";

// 고양이 전체 데이터 조회 -> GET
export const readAllCat = (req: Request, res: Response) => {
  try {
    const cats = Cat;
    // throw new Error("db connect error"); => 직접 에러를 던져볼 수 있습니다.
    res.status(200).send({
      success: true,
      data: {
        cats,
      },
    });
  } catch (error) {
    res.status(400).send({
      success: false,
      error: error.message,
    });
  }
};

// 특정 고양이 데이터 조회 -> GET
export const readCat = (req: Request, res: Response) => {
  try {
    const params = req.params;
    const cat = Cat.find((cat) => {
      return cat.id === params.id;
    });
    // throw new Error("db connect error"); => 직접 에러를 던져볼 수 있습니다.
    res.status(200).send({
      success: true,
      data: {
        cat,
      },
    });
  } catch (error) {
    res.status(400).send({
      success: false,
      error: error.message,
    });
  }
};

// 새로운 고양이 추가 -> POST
export const createCat = (req: Request, res: Response) => {
  try {
    const data = req.body;
    // console.log(req.body);
    console.log(data);
    Cat.push(data);
    res.status(200).send({
      success: true,
      data: {},
    });
  } catch (error) {
    res.status(400).send({
      success: false,
      error: error.message,
    });
  }
};

// 고양이 데이터 업데이트 -> PUT
export const updateCat = (req: Request, res: Response) => {
  try {
    const params = req.params;
    const body = req.body;
    let result;
    Cat.forEach((cat) => {
      if (cat.id === params.id) {
        cat = body;
        result = cat;
      }
    });

    res.status(200).send({
      success: true,
      data: {
        cat: result,
      },
    });
  } catch (error) {
    res.status(400).send({
      success: false,
      error: error.message,
    });
  }
};

// 고양이 데이터 부분 업데이트 -> PATCH
export const patchCat = (req: Request, res: Response) => {
  try {
    const params = req.params;
    const body = req.body;
    let result;
    Cat.forEach((cat) => {
      if (cat.id === params.id) {
        cat = { ...cat, ...body }; // 구조 분해 할당 : 중복되어진 key에 대한 value값을 교체해줍니다.
        result = cat;
      }
    });

    res.status(200).send({
      success: true,
      data: {
        cat: result,
      },
    });
  } catch (error) {
    res.status(400).send({
      success: false,
      error: error.message,
    });
  }
};

// 고양이 데이터 삭제 -> DELETE
export const deleteCat = (req: Request, res: Response) => {
  try {
    const params = req.params;
    const newCat = Cat.filter((cat) => cat.id !== params.id); //임시로 해당 요청된 값을 제외간 값을 가져오도록 처리
    res.status(200).send({
      success: true,
      data: newCat,
    });

    res.status(200).send({
      success: true,
      data: {
        cat: newCat,
      },
    });
  } catch (error) {
    res.status(400).send({
      success: false,
      error: error.message,
    });
  }
};

그리고 이를 import 하여 사용하게 되는 router는 이렇게 간결해집니다.

import { Router } from "express";
import {
  createCat,
  deleteCat,
  patchCat,
  readAllCat,
  readCat,
  updateCat,
} from "./cats.service";

const router = Router();

router.get("/cats", readAllCat);

router.post("/cats", readCat);

router.get("/cats/:id", createCat);

router.put("/cats/:id", updateCat);

router.patch("/cats/:id", patchCat);

router.delete("/cats/:id", deleteCat);

export default router;

감사합니다.

profile
항상 준비하는 엔지니어

0개의 댓글