Home MVC 패턴
Post
X

MVC 패턴

MVC 패턴을 적용한 express 서버를 구현해보자.


MVC 패턴

모델-뷰-컨트롤러 (Model-View-Controller, MVC) 는 소프트웨어 디자인 패턴입니다.

비즈니스 로직을 분리해 서로 영향없이 유지보수할 수 있는 애플리케이션을 만들 수 있습니다.

  • Model : 데이터 관련 작업 담당
  • View : 사용자 인터페이스 담당
  • Controller : 데이터 (Model)과 사용자 인터페이스 (View) 요소 연결 담당

View 설정 (+ ejs)

먼저 ejs 모듈을 설치하고 app.jsview engine을 설정합니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import express from "express";
import path from "path";
import bodyParser from "body-parser";

const app = express();
const __dirname = path.resolve();

// 정적 파일
app.use("/", express.static(`${__dirname}/src/public`));

// 앱 세팅
app.set("views", "./src/views");
app.set("view engine", "ejs");

// 미들웨어
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));

// 3000 포트로 서버 오픈
app.listen(3000, () => {
  console.log("express server on port 3000");
});

test 파일 만들기

views 폴더안에 간단한 test.ejs 파일을 만듭니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
<!-- test.ejs -->
<!DOCTYPE html>
<html lang="ko">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Root</title>
  </head>
  <body>
    Hello World!
  </body>
</html>

Router 설정

Router는 특정 주소로 요청이 들어오면 주소와 HTTP method 별로 Controller와 연결하는 역활을합니다.

또한, 요청과 함께 받은 데이터들의 유효성 검사 등도 Router에서 담당합니다.

Routes 폴더를 만들고 route_test.js 파일을 만들어 express router를 작성합니다.

1
2
3
4
5
6
7
8
9
10
import express from "express";
import ctrl from "../controller/controller-test.js";

const Router = express.Router();

Router.get("/", ctrl.output.test);

Router.get("/test", ctrl.process.test);

export default Router;

서버 파일인 app.js와 라우터 파일 route_test.js 파일을 미들웨어로 연결합니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import express from "express";
import path from "path";
import bodyParser from "body-parser";
import testRouter from "./src/routes/route_test.js";

const app = express();
const __dirname = path.resolve();

// 정적 파일
app.use("/", express.static(`${__dirname}/src/public`));

// 앱 세팅
app.set("views", "./src/views");
app.set("view engine", "ejs");

// 미들웨어
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));

// router
app.use("/", testRouter);

// 3000 포트로 서버 오픈
app.listen(3000, () => {
  console.log("express server on port 3000");
});

Controller 설정

Controller는 요청을 처리하고 응답하는 역할을 합니다.

Model과 View 간의 중간 다리 역할로 필요에따라 Model과 소통하여 받은 데이터를 View(클라이언트)로 응답합니다.

controllers 폴더를 만들고 controller_test.js 파일에 output, process 객체로 나누어 작성하겠습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import model_test from "../models/model_test.js";

const output = {
  test: (req, res) => {
    res.render("test");
  },
};

const process = {
  test: async (req, res) => {
    const data = await model_test.getUsers();

    res.send(data);
  },
};

export default { output, process };

Models 설정

Model은 Controller로 부터 요청을 받아 DB에 접근해 CRUD 로직을 처리합니다.

mysql2 모듈의 createPool을 활용해보겠습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import mysql from "mysql2/promise";

const pool = await mysql.createPool({
  host: process.env.DB_HOST, //실제로 연결할 데이터베이스의 위치
  user: process.env.DB_USER,
  password: process.env.DB_PASSWORD,
  database: "user", //데이터베이스 이름
  port: 3306,
  connectionLimit: 30,
});

const conn = await pool.getConnection(async (conn) => conn);

class userStorage {
  static async getUsers() {
    try {
      const [rows] = await conn.query("SELECT * FROM users");

      return rows;
    } catch (err) {
      console.log(err);
    } finally {
      conn.release();
    }
  }
}

export default userStorage;

TEST

서버를 열고 잘 동작 하는 지 확인해보겠습니다

  1. 먼저 서버를 실행합니다.

    test-01

  2. localhost:3000 주소로 접속해봅니다.

    test-02
    작성한 test.ejs 파일이 잘 출력되는 것을 확인할 수 있습니다.

  3. localhost:3000/test 주소로 접속해보겠습니다.

    test-03
    model에서 받아온 데이터가 잘 출력되는 것을 확인할 수 있습니다.


결론

  • 디렉터리 구조
    mvc-diretory

MVC 패턴의 틀을 잡았으니 다음 포스트에서 추가로 기능을 구현해보겠습니다.

먼저 간단하게 로그인 기능을 구현해보겠습니다.

이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.