객체 인스턴스가 오직 한개만을 생성하게 하는 패턴을 말합니다.
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라는 파일로 분할하여 처리합니다. 이렇게 되면 유지보수가 훨씬 쉬워집니다.
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;
감사합니다.