Node.js로 MVC 패턴을 연습해보자. 디자인 패턴을 사용하면 유지보수하기 좋고 협업에 효율적인 코드를 작성할 수 있다.
1. MVC 패턴이란
MVC 패턴은 Model, View, Controller의 약자이다. 이는 세 가지 주요 구성 요소로 로직을 분리하여 개발하는 디자인 패턴이다.
- Model : 데이터와 비즈니스 로직을 관리
- View : 사용자에게 데이터를 표시, 여기서 View는 Model을 알지 못함
- Controller : 사용자 요청을 처리하고, Model과 View 연결을 처리
1-1. 의존성
간단하게 설명하자면, 다음과 같은 과정이 이루어진다.
사용자 요청 -> Controller -> Model -> Controller -> View -> 사용자 응답
2. 폴더 구성
Node.js로 MVC 패턴을 구성할 때 적절한 폴더 구성이 중요하다. 다음과 같이 폴더를 분리한다.

3. Model
DB를 연동하지 않고, 일단 다음과 같이 임시 Model를 작성해준다. 로그인을 구현할 것이기 때문에 realId와 realPw를 임시 객체로 만들어주고 사용할 것이다.
exports.userInfo = () =>{
return {
realId : 'soojin',
realPw: 'soojin1234',
};
};
4. View
View에서는 템블릿 엔진인 EJS를 사용하여 데이터를 HTML로 렌더링한다. EJS에서는 <%%>와 같은 문법을 사용해 JavaScript 데이터를 HTML에 삽입해줄 수 있다.
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>MVC 공부</title>
<!-- Axios CDN -->
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<style>
label {
display: flex;
}
label span {
width: 80px;
}
.success {
color: blue;
font-size: 1.2rem;
font-weight: 700;
}
.error {
color: red;
font-size: 1.2rem;
font-weight: 700;
}
</style>
</head>
<body>
<form name = "login">
<label for="userID">
<span>아이디</span>
<input type="text" name="userId" id="userId" required>
</label>
<br/>
<label for="userPw">
<span>비밀번호</span>
<input type="password" name="userPw" id="userPw" required>
</label>
<br/> <br/>
<button type="button" onclick="clickLogin()">로그인</button>
</form>
<div class="login-result"></div>
</body>
<script>
function clickLogin() {
const form = document.forms["login"];
const loginResult = document.querySelector(".login-result");
const data = {
userId : form.userId.value,
userPw : form.userPw.value,
};
console.log(data);
// 유효성 검증을 하자
if (!form.userId.checkValidity() || !form.userPw.checkValidity()) {
loginResult.innerText = "아이디와 비밀번호는 필수로 입력해주세요.";
return;
}
axios({
url : "/login",
method : "post",
data : data,
}).then((res)=>{
console.log(res.data);
if (res.data.isSuccess) {
loginResult.textContent = `${res.data.userId}님 안녕하세요 :0`;
loginResult.classList.add("success");
loginResult.classList.remove("error");
} else {
loginResult.textContent = "아이디 또는 비밀번호가 오류입니다 :(";
loginResult.classList.add("error");
loginResult.classList.remove("success");
}
});
};
</script>
</html>
5. Controller
Controller통해서 Model과 View를 연걸한다.
const User = require("../model/User");
exports.main = (req, res) => {
res.render("index", {userInfos: User.userInfo()});
};
exports.login = (req, res) => {
console.log(req.body);
console.log(User.userInfo().realId);
if (User.userInfo().realId === req.body.userId && User.userInfo().realPw === req.body.userPw) {
res.send({isSuccess: true, userId: req.body.userId });
} else res.send({isSuccess : false});
};
6. Router
Express를 이용해 라우터를 작성한다. 여기서 라우터의 역할은 URL 요청을 적절한 Controller로 전달하여 요청을 처리하는 일을 한다. URL로 경로를 분리하면 코드의 가독성이 높아지고, 기능별로 모듈화가 가능한다는 것!
const express = require("express");
const router = express.Router();
const controller = require("../controller/Cuser");
// GET /
router.get('/', controller.main);
router.post('/login', controller.login);
module.exports = router;
7. 어플리케이션 초기화
여기서 Express 어플리케이션을 초기화하고 라우터를 연결한다.
const express = require("express");
const app = express();
const PORT = 8080;
// 1. 뷰 폴더 설정
app.set("view engine", "ejs");
app.set("views", "./views");
// 2. body-parser 설정
app.use(express.urlencoded({extended:false}));
app.use(express.json());
// 라우터 분리
const userRouter = require('./routes/user');
app.use('/', userRouter);
app.listen(PORT, ()=>{
console.log(`http://localhost:${PORT}`);
});
8. 결론
MVC 패턴을 사용하는 것과 사용하지 않은 코드는 생각보다 차이가 크다는 것을 알 수 있다. 비교적 짧은 코드는 코드를 읽기에 어렵지 않지만, 기능이 많아진다면 코드가 길어지고 유지보수성이 떨어질 것이다. 그리고 개발은 혼자가 아닌 여러 사람과 함께하기 때문에 코드를 파악하는데 어려움을 줄 수 있다. MVC 패턴을 적용하는게 처음에는 쉽지는 않지만 로직을 잘 파악한다면 어렵지 않게 구성할 수 있을 것이다.
'🙋♀️ Server' 카테고리의 다른 글
| [Server] Database 설계 & SQL 1452 문제 해결 (2) | 2024.12.17 |
|---|---|
| [Web] MySQL + Node.js로 MVC 패턴 적용 (2) | 2024.12.03 |
| [Web] let, var, const의 차이 (2) | 2024.11.09 |
| [Spring] 스프링 입문 - thymeleaf 동작 환경 과정 (0) | 2024.09.23 |
| [Java] 객체지향이라는게 뭘까 (0) | 2024.09.21 |