싱글톤 패턴을 적용한다.

import * as express from 'express';
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() {
		//* logging middleware
		this.app.use((req, res, 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();

지금까지의 코드가 위와 같이 바뀌었다.

위와 같이 하면

  • 라우터의 분리 (cats, users, blogs)가 가능해지고
  • 기능별 MiddleWare의 관리가 가능해진다

Service Pattern의 적용

cats.service.ts 라는 파일을 만들어서 router에서 하는 로직을 여기서 만듬

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

//* READ 고양이 전체 데이터 다 조회 -> 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,
		});
	}
};

//* READ 특정 고양이 데이터 조회 -> GET
export const readCat = (req: Request, res: Response) => {
	try {
		const params = req.params;
		console.log(params);
		const cat = Cat.find(cat => {
			return cat.id === params.id;
		});
		res.status(200).send({
			success: true,
			data: {
				cat,
			},
		});
	} catch (error) {
		res.status(400).send({
			success: false,
			error: error.message,
		});
	}
};

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

//* UPDATE 고양이 데이터 업데이트 -> 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,
		});
	}
};

//* UPDATE 고양이 데이터 부분적으로 업데이트 -> PATCH
export const updatePartialCat = (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 };
				result = cat;
			}
		});
		res.status(200).send({
			success: true,
			data: {
				cat: result,
			},
		});
	} catch (error) {
		res.status(400).send({
			success: false,
			error: error.message,
		});
	}
};

//* DELETE 고양이 데이터 삭제 -> 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,
		});
	} catch (error) {
		res.status(400).send({
			success: false,
			error: error.message,
		});
	}
};

이렇게 만들면

기존의 cats.route.ts

파일은 아래와 같이 된다.

import { Cat, CatType } from './cats.model';
import { Router } from 'express';
import { NextFunction } from 'express-serve-static-core';
import {
	createCat,
	deleteCat,
	readAllcat,
	readCat,
	updateCat,
	updatePartialCat,
} from './cats.service';

const router = Router();

router.get('/cats', readAllcat);
router.get('/cats/:id', readCat);
router.post('/cats', createCat);
router.put('/cats/:id', updateCat);
router.patch('/cats/:id', updatePartialCat);
router.delete('/cats/:id', deleteCat);


export default router;

위와 같이 정리가 되며

이렇게 되면 가독성 및 구조의 정리가 된다.

그리고 nest.js 에서의 구조가 위를 강제하고 있기 때문에

이를 염두해두고 가는 것이 중요하다.