2023-05-22 19:54:53

MVC 디자인 패턴

MVC 패턴은 Model, View, Controller의 약자로 각자 맡은 역할에 맞게 소스코드를 폴더 별로 구분하여 파일을 관리하는 소프트웨어 설계 아키텍쳐를 말합니다. 확장성과 코드의 유지보수성을 높여주어 프로그램을 개발할때 많이 사용되며 MVC에 정의된 각각의 용도에 맞게 사용해야 하는게 중요합니다.

 

  • Model : 어플리케이션의 데이터 및 비지니스 논리를 나타내어 데이터베이스와 연결하여 상호 작용하거나 데이터를 관리, 규칙과 제약조건을 처리합니다.
  • View : 데이터를 사용자에게 표시하는 역할로 사용자가 볼 수 있는 공간을 정의합니다.
  • Controller : Model과 View 사이에 중재자의 역할로 사용자가 요청한 데이터를 Model과 통신하여 처리하고 처리한 데이터를 View를 통해 사용자에게 보여주게 됩니다.

 

npm

npm은 Node Package Manager의 약자로 Node.js에서 사용할 수 있는 패키지를 관리하고 배포하는 플랫폼을 말합니다. 

세계적으로 가장 큰 소프트웨어 레지스트리 중에 하나이며 수백만개의 패키지를 호스팅합니다.

 

package.json

package.json이란 Node.js 프로젝트에 사용되는 필수 파일로 프로젝트의 메타 데이터를 저장합니다.

보통 처음 프로젝트를 생성할 때 npm init을 통해 생성한 후 사용합니다.

// 프로젝트 초기화
// y 옵션은 기본 설정으로 package.json을 생성하게 해줌
npm init -y

// package.json 내용

{
  // name : 프로젝트의 이름
  "name": "nodejs_mvc",		
  // version : 프로젝트의 버전
  "version": "1.0.0",
  // description : 프로젝트의 간단한 설명
  "description": "",
  // main : 프로젝트의 진입점을 가르키는 파일 이름
  "main": "app.js",
  // scripts : 스크립트 커맨드를 정의하는 부분
  // 보통 "start": "node app.js"을 입력하여 프로젝트를 실행하기 편하게 해줌
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  // keywords : 키워드를 정의
  "keywords": [],
  // author : 프로젝트 작성자
  "author": "",
  // license : 프로젝트의 라이센스를 나타내며 기본적으로 ISC로 설정
  "license": "ISC"
}

 

express

express는 웹 어플리케이션을 위한 강력한 기능을 제공 해주는 프레임워크로 간결하고 유연하게 Node.js 웹 어플리케이션을 만들게 도와줍니다. HTTP 유틸리티 메소드 및 미들웨어를 통해 쉽고 빠르게 API를 작성하게 도와주기 때문에 유명한 프레임워크들이 Express를 기반으로 두어 개발되었습니다.

// Express 모듈 설치
npm install express

 

ejs

ejs는 Embedded JavaScript의 약자로 자바스크립트가 내장되어 있는 템플릿을 말합니다.

<% %> 를 활용해서 문서내에서 for문을 사용하거나 <%= %>을 사용하여 변수만 사용 할 수 있게 도와줍니다.

// ejs 설치
npm install ejs

 

Mysql2

다른글을 통해 데이터베이스를 소개하였으니 설치 방법만 설명하고 넘어가겠습니다.

// mysql2 모듈 가져오기
npm install mysql2

 

서버 만들기

express, mysql2, ejs를 사용하여 서버를 열고 데이터베이스와 연결 후 데이터가 가져와지는거 까지의 과정을 mvc 디자인 패턴을 적용하여 간단한 코드를 작성해보자.

 

파일 전체 트리 구조

 

app.js

// express 모듈을 가져옴
const express = require("express");	
// 설정해둔 라우터 파일을 가져옴
const mainrouter = require("./routers/route");
// join을 사용하기 위해 내장 모듈을 가져옴
const path = require("path");	

// express 사용하기 위해 app에 할당
const app = express();	

// views 파일이 어딨는지 경로 설정
app.set("views", path.join(__dirname, "pages"));
// view engine으로 ejs를 사용하겠다고 선언
app.set("view engine", "ejs");

// 깊은 객체를 사용하지 않기 위한 설정
// url 인코딩된 데이터를 파싱
// false면 기본 내장된 querystring 사용
app.use(express.urlencoded({ extended: false }));	

// '/' 로 요청이 들어오면 이쪽 router로 요청을 보냄
// app.use("/login", mainrouter); 이건 /login으로 시작하는 url요청이 오면 mainrouter로 요청을 보내라는 뜻
app.use(mainrouter);

// 8080 포트를 사용하여 서버를 대기 상태로 만듬
app.listen(8080, () => {
  console.log("Server On");
});

routers/route.js

const router = require("express").Router();
const { mainpage } = require("../controllers/controller");

// '/' 즉 localhost:8080/ 으로 url 요청시 mainpage 함수 실행
router.get("/", mainpage);

module.exports = router;

 

models/config.js

const mysql2 = require("mysql2/promise");

const mysql = mysql2.createPool({
  host: "127.0.0.1", 		// 데이터베이스 호스트
  user: "root",			// 데이터베이스 아이디
  password: "root",		// 데이터베이스 패스워드
  database: "test",		// 데이터베이스 이름
  multipleStatements: "true", // 다중 쿼리 기능 true는 사용하겠다는 뜻
});

module.exports = mysql;

 

models/model.js

const mysql = require("./config");

exports.init = async () => {
  try {
    // SELECT 문을 사용하여 테이블이 있는지 확인하고 없으면 에러
    await mysql.query("SELECT * FROM blog_users");
  } catch (error) {
    // 테이블이 없으면 에러가 발생하고 catch 실행
    // 테이블을 만들어줌
    await mysql.query(
      "CREATE TABLE blog_users (id INT AUTO_INCREMENT, user_id VARCHAR(20), user_pw VARCHAR(200), PRIMARY KEY(id)); INSERT INTO blog_users (user_id, user_pw) VALUES ('test', 'test');INSERT INTO blog_users (user_id, user_pw) VALUES ('test2', 'test2');"
    );
  }
};

exports.userAll = async () => {
  try {
    // user정보를 모두 가져옴
    const [data] = await mysql.query("SELECT * FROM blog_users;");
    return data;
  } catch (error) {
    console.error(error);
  }
};

models/index.js

const { init, userAll } = require("./model");
// users 테이블이 없으면 새로 만들어줌
init();

module.exports = { userAll };

 

controllers/controller.js

const { userAll } = require("../models");

exports.mainpage = async (req, res) => {
  try {
    const result = await userAll();
    res.render("main", { result });
  } catch (error) {
    console.error(err);
  }
};

pages/main.ejs

<!DOCTYPE html>
<html lang="en">
  <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>Document</title>
  </head>
  <body>
    <h2>hello world</h2>
    <ul>
      <!-- controller에서 render할때 같이 넘겨준 데이터를 forEach문을 돌려 출력해줌 -->
      <% result.forEach((el)=>{ %>
      <li>
        <span><%= el.user_id%></span>
      </li>
      <% }); %>
    </ul>
  </body>
</html>

 

데이터베이스에 있는 유저 정보를 Workbench에서 확인
데이터베이스의 내용을 가져와 웹페이지에서 잘 보여지는것을 볼 수 있다.

 

728x90