[Node.js] 유튜브 서비스 - router 사용하여 하나의 파일에서 모든 요청 연결하기
이전에 channels.js에서 만든 채널 서비스와, users.js에서 만든 유저 서비스를 한 파일에서 가동하려고 한다.
하지만 각자의 파일에 const app = express();와 같이 app을 정의하고 app.listen()을 통해 서버를 열었다.
express의 router를 활용하여 app.js라는 대장 파일에서 두 파일을 관리하여 실행할 수 있도록 구현해보자.
app.js
const express = require("express");
const app = express();
app.listen(3000);
const userRouter = require("./routes/users");
const channelRouter = require("./routes/channels");
app.use("/", userRouter);
app.use("/channels", channelRouter);
대장 파일인 app.js에서는 다른 파일에서처럼 app = express()를 통해 app을 정의하고
app.listen()을 통해 서버를 열어야 한다.
그리고 users.js와 channels.js로부터 모듈을 전달받아 userRouter, channelRouter로 저장해두고
app.use()를 통해 전달받은 모듈을 사용하도록 하였다.
users.js / channels.js
const express = require("express");
const router = express.Router();
router.use(express.json());
let userDb = new Map();
var id = 1;
// 1. 로그인
router.post("/login", (req, res) => {
let body = req.body;
let userId = body.id;
let password = body.password;
let loginUser = {};
// 정보가 누락된 경우 예외 처리
if (!userId) {
res.status(400).json({
message: "id가 포함되어있지 않습니다.",
});
} else if (!password) {
res.status(400).json({
message: "password가 포함되어있지 않습니다.",
});
} else {
userDb.forEach((val, idx) => {
if (val.id === userId) {
loginUser = val;
}
});
if (Object.keys(loginUser).length !== 0) {
if (loginUser.password === password) {
res.json({
message: `${loginUser.name}님 환영합니다!`,
});
} else {
res.json({
message: "패스워드가 일치하지 않습니다",
});
}
} else {
res.json({
message: "아이디가 일치하지 않습니다.",
});
}
}
});
// 2. 회원가입
router.post("/join", (req, res) => {
let body = req.body;
let userId = body.id;
let password = body.password;
let userName = body.name;
let isIdDuplicated = false;
for (let value of userDb.values()) {
if (value.id === userId) {
isIdDuplicated = true;
break;
}
}
// 정보가 누락된 경우 예외 처리
if (!userId) {
res.status(400).json({
message: "id가 포함되어있지 않습니다.",
});
} else if (!password) {
res.status(400).json({
message: "password가 포함되어있지 않습니다.",
});
} else if (!userName) {
res.status(400).json({
message: "name이 포함되어있지 않습니다.",
});
}
// 중복된 id인 경우 예외 처리
else if (isIdDuplicated) {
res.status(400).json({
message: "이미 가입되어있는 id입니다.",
});
} else {
userDb.set(id++, body);
res.status(201).json({
message: `${userName}님 환영합니다`,
});
}
});
// 3. 회원 개별 조회
router.get("/users/:id", (req, res) => {
let { id } = req.params;
id = parseInt(id);
const user = userDb.get(id);
if (user) {
res.json({
userId: user.id,
name: user.name,
});
} else {
res.status(404).json({
message: `${id}에 해당되는 유저가 없습니다.`,
});
}
});
// 4. 회원 개별 탈퇴
router.delete("/users/:id", (req, res) => {
let { id } = req.params;
id = parseInt(id);
const user = userDb.get(id);
if (user) {
userDb.delete(id);
res.json({
message: `${user.name}님이 탈퇴되었습니다.`,
});
} else {
res.status(404).json({
message: `${id}에 해당되는 유저가 없습니다.`,
});
}
});
module.exports = router;
기존에 사용했던 app = express()가 아닌, router = express.Router()를 사용하여 라우터로 역할을 하게 하였다.
따라서 app.get(), app.post()등과 같이 요청을 처리했던 app들을 모두 router로 바꾸어주어야 한다.
마지막으로 app.js에서도 users.js의 router를 사용할 수 있도록 마지막에 module.exports = router를 처리해주면 된다.
const express = require("express");
const router = express.Router();
router.use(express.json());
let channelDb = new Map();
var id = 1;
router
.route("/channels")
// 채널 전체 조회
.get((req, res) => {
var channels = [];
channelDb.forEach((val) => {
channels.push(val);
});
if (channels.length) {
res.json(channels);
} else {
res.status(404).json({
message: "조회할 채널이 없습니다.",
});
}
})
// 채널 생성
.post((req, res) => {
let { channelTitle } = req.body;
if (channelTitle) {
channelDb.set(id++, req.body);
res.status(201).json({
message: `${channelTitle} 채널이 생성되었습니다.`,
});
} else {
res.status(400).json({
message: "요청이 올바르지 않습니다.",
});
}
});
router
.route("/channels/:id")
// 채널 개별 조회
.get((req, res) => {
let { id } = req.params;
id = parseInt(id);
let channel = channelDb.get(id);
if (channel) {
res.json({
channelTitle: channel.channelTitle,
});
} else {
res.status(404).json({
message: "요청이 올바르지 않습니다.",
});
}
})
// 채널 개별 수정
.put((req, res) => {
let { id } = req.params;
id = parseInt(id);
let newChannelTitle = req.body.channelTitle;
let channel = channelDb.get(id);
let oldChannelTitle = channel.channelTitle;
if (channel) {
channel.channelTitle = newChannelTitle;
channelDb.set(id, channel);
res.json({
message: `${oldChannelTitle} 채널이 ${newChannelTitle} 채널로 수정되었습니다.`,
});
} else {
res.status(404).json({
message: "요청이 올바르지 않습니다.",
});
}
})
// 채널 개별 삭제
.delete((req, res) => {
let { id } = req.params;
id = parseInt(id);
let channel = channelDb.get(id);
if (channel) {
channelDb.delete(id);
res.json({
message: `${channel.channelTitle} 채널이 삭제되었습니다.`,
});
} else {
res.status(404).json({
message: "요청이 올바르지 않습니다.",
});
}
});
module.exports = router;
마찬가지로 channels.js에서도 app을 모두 router로 변경해주고, exports를 통해 app.js와 router를 연결해주었다.
다만 app.js에서 channels.js의 router를 사용할 때 url을 "/channels"로 지정해주었다.
이에 따라 channels.js에 존재하는 요청들에 모두 포함되어있었던 /channels를 app.js에서 지정하도록 하였고,
url들을 수정해주었다.
app.js 실행 후 확인
이제 app.js를 통해 서버를 열고 users.js와 channels.js의 요청들이 잘 처리되는지 확인해보자.
모두 잘 작동하는 모습을 볼 수 있다.
위와 같이 여러 파일에서 서로 다른 종류의 api들을 구현하더라도 router를 통해 연결하여
대장 파일인 app.js에서 모든 요청들을 연결시켜줄 수 있다.