웹 풀스택

[Node.js] 유튜브 서비스 - router 사용하여 하나의 파일에서 모든 요청 연결하기

kevinmj12 2025. 2. 21. 16:15

이전에 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에서 모든 요청들을 연결시켜줄 수 있다.