mvc 패턴 예제mvc 패턴 정리MVC 패턴 구현MVCMVP

MVC 패턴 웹 애플리케이션 구축하기

KUKJIN LEE
KUKJIN LEE
2024년 2월 18일
153

MVC (Model-View-Controller) 패턴은 소프트웨어 디자인 패턴으로, 애플리케이션을 모델, 뷰 및 컨트롤러 세 가지 주요 구성 요소로 분리하여 개발하는 방법입니다. Node.js와 Express.js를 활용하여 MVC 패턴을 구현하려면 다음과 같은 구조로 폴더를 구성할 수 있습니다.

Models란?

데이터와 데이터 처리를 담당합니다. 데이터의 유효성 검사, 저장 및 가져오기와 같은 작업을 처리합니다.

Views란?

사용자에게 보여지는 내용을 담당합니다. 클라이언트에게 데이터를 보여주는 역할을 합니다.

Controller란?

모델과 뷰 사이의 중간 역할을 수행합니다. 클라이언트의 요청을 받아 해당 요청에 맞는 모델 작업을 처리하고, 그 결과를 뷰에 전달합니다.

MVC 패턴 폴더 구조 예시

app.js는 Express 애플리케이션의 진입점이며, 라우팅, 미들웨어 설정 등을 관리합니다. routes 폴더 내에서는 각각의 엔티티(사용자, 포스트 등)에 대한 라우팅을 분리하여 관리합니다.

이러한 구조를 기반으로, Express.js의 미들웨어 및 라우팅을 활용하여 클라이언트의 요청을 처리하고 데이터를 모델과 뷰 사이에서 조율하는 방식으로 MVC 패턴을 구현할 수 있습니다.

root/
├─ models/
│  ├─ user.js
│  └─ post.js
│
├─ views/
│  ├─ home.ejs
│  └─ profile.ejs
│
├─ controllers/
│  ├─ userController.js
│  └─ postController.js
│
├─ public/ (정적 파일)
│
├─ routes/
│  ├─ index.js
│  ├─ userRoutes.js
│  └─ postRoutes.js
│
├─ app.js
└─ package.json

app.js(Express 설정)

Express 프레임워크를 사용하여 웹 애플리케이션을 구축하고, 라우팅을 중심으로 웹 요청을 처리하는 방법입니다. 라우팅은 클라이언트의 요청에 따라 적절한 핸들러 함수를 호출하여 해당 요청을 처리하는 매커니즘입니다.

기존 설정과 비교했을 때, app.use('/users', userRoutes)가 추가 된걸 확인할 수 있습니다.

 

const express = require('express');
const app = express();
const userRoutes = require('./routes/userRoutes');
const postRoutes = require('./routes/postRoutes');

app.use(express.json());
app.use('/users', userRoutes);
app.use('/posts', postRoutes);

app.listen(3000, () => {
    console.log('Server is running on port 3000');
});

Routes

사용자 관련 API 엔드포인트를 라우팅 파일에 정의하여 사용자 컨트롤러를 통해 두 가지 종류의 HTTP 요청을 처리하는 방법을 보여줍니다.

const express = require('express');
const router = express.Router();
const userController = require('../controllers/userController');

router.get('/', userController.getAllUsers);
router.post('/', userController.createUser);

module.exports = router;

Controllers

사용자 관련 로직을 처리하는 컨트롤러입니다. 코드는 두 가지 예를 통해 API 요청에 대한 처리 방법을 보여줍니다.

const { User } = require('../models');

exports.getAllUsers = async (req, res) => {
    try {
        const users = await User.findAll();
        res.json(users);
    } catch (error) {
        res.status(500).json({ message: 'Error retrieving users' });
    }
};

exports.createUser = async (req, res) => {
const { name, email } = req.body;
    try {
        const newUser = await User.create({ name, email });
        res.json(newUser);
    } catch (error) {
        res.status(500).json({ message: 'Error creating user' });
    }
};

Models

Sequelize를 사용하여 데이터베이스 모델을 정의하는 파일의 예제입니다. Sequelize는 Node.js에서 SQL 데이터베이스를 다루기 위한 프로미스 기반 ORM(Object-Relational Mapping) 라이브러리입니다.

const { DataTypes } = require('sequelize');
const sequelize = require('../database');

const User = sequelize.define('User', {
    name: {
        type: DataTypes.STRING,
        allowNull: false
    },
    email: {
        type: DataTypes.STRING,
        allowNull: false
    }
});

module.exports = User;

MVC 패턴 정리

간단한 예시 코드입니다. Sequelize를 사용하여 데이터베이스 모델을 정의하기 위해 별도의 설정이 필요하고, Express.js를 활용하여 라우팅과 컨트롤러 구성의 경우 각 파일의 경로 및 설정에 따라 코드 오류 처리, 보안 등 추가 사항을 고려해야합니다.

현재 글은 MVC 패턴에 대해서 정리했지만, MVCS(Service) 패턴을 권장드립니다. 서비스 레이어를 추가하여 컨트롤러 코드를 더욱 깔끔하게 유지하고, 재사용 가능한 비즈니스 로직을 모듈화할 수 있습니다. 로직을 분리하는 것은 MVC 패턴을 확장하고 보다 모듈화 할 수 있습니다.

 

관련 글

[SQL 입문] 필요한 데이터만 콕 집어 가져올 수 있는 WHERE 절

사용자는 테이블에 있는 모든 데이터를 다 보고 싶어 하지는 않습니다. 오히려 특정 항목에 대한 데이터만 가져오고 싶을 때가 훨씬 많습니다. 예를 들어, 어떤 사용자의 이메일이나 ID는 알고 있는데, 그 사람이 언제 우리 앱에 가입했는지 확인하고 싶다고 가정해 봅시다...

2026년 1월 27일10

SQL에서 SELECT란 무엇인가?

데이터베이스를 거대한 서류 보관함이라고 생각하면 됩니다. 보관함 안에는 수많은 데이터가 차곡차곡 쌓입니다. SELECT는 이 보관함에서 "내가 원하는 정보를 찾아줘!"라고 요청하는 명령어입니다. 이 과정을 전문 용어로 '쿼리(Query)'라고 부릅니다. &nbs...

2026년 1월 26일10

[SQL 기초] "언제 하나씩 다 넣어?" 데이터 한 번에 넣기

개발을 하다 보면 데이터베이스(DB)에 샘플 데이터를 대량으로 넣어야 할 때가 있습니다. 메뉴 100개를 추가해야 하는데 INSERT 문을 100번 쓰고 있다면? 너무 비효율적이죠! 오늘은 SQL에서 여러 데이터를 한 번에 넣는 '다중 삽입(Multiple Inse...

2026년 1월 21일13

SQL 데이터 삽입하기

데이터가 없는 데이터베이스는 연료 없는 로켓과 같습니다. 이제 'Missions' 테이블에 새로운 행(row)을 추가하는 방법을 알아보겠습니다. "삽입(Inserting)"은 '데이터 추가'를 의미합니다. 기존 Missions 테이블 ...

2026년 1월 20일12