싱글톤 패턴을 적용한다.
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 에서의 구조가 위를 강제하고 있기 때문에
이를 염두해두고 가는 것이 중요하다.