MVC design pattern

📅 TIL #68



🎯 Achievement Goals


  • MVC 디자인 패턴과 같이, 코드를 각각 다른 부분으로 나누어 작성해야 하는 이유를 이해할 수 있다.
  • Model, View, Controller가 각각 어떤 역할을 하는지 이해할 수 있다.
  • 마이그레이션의 개념과 필요성을 이해할 수 있다.





👉 MVC 패턴


오늘은 MVC(Model-View-Controller)로 대표되는 UI와 비즈니스 로직, 그리고 모델을 분리하여 개발하는 소프트웨어 디자인 패턴에 대해서 공부를 했다.


mvc


여기서 갑자기 ORM이 나왔는데, ORM은 Model을 기술하는 도구이다. 이것을 통해서 데이터베이스 세계와 프로그래밍 언어 사이의 개념의 간극을 줄여줄 수 있다.

오늘 학습의 목표는 ORM을 이용하여 SQL문을 직접 작성하지 않고 엔티티를 객체로 표현하는 방법을 익히는 것이었다.



mvc22


Model

모델은 데이터의 정보를 가지고 있다. 그리고 데이터베이스와 이야기를 하고 데이터베이스로부터 받은 값이나 직접 가지고 있는 값을 가지고 controller와 이야기를 한다.

직접 view랑 이야기하는 경우는 없다.


View

controller랑만 이야기를 한다. 액션이나 이벤트를 전달한다.


Controller

view 로 부터 액션이나 이벤트를 받고 가공을 해서 Model에게 던져준다. Model에게서 받은 데이터도 가공을 거쳐서 다시 view에게 던져준다.

👉 ORM


Object-Relational Mapping의 약자로관계형 데이터베이스와 객체사이의 통역사 역할을 한다.

orm

내가 만든 자바스크립트 문법을 자동으로 SQL로 만들 수 있다.

즉, 접근 자체를 프로그래밍언어에서 맞출 수 있도록 도와주는 것이 ORM이다.



👉 sequelize

sequelize


그래서 오늘 배운 ORM중의 하나가 sequelize이다. 오늘 모든 과제는 공식문서만 보고 풀었다. 공식문서를 보면서 이해하는게 아직은 많이 힘들지만 그래도 오늘은 sequelize 공식문서만 보고도 잘 해결된 것 같아서 다행이다.

Getting Start

$ npm i --save sequelize
$ npm i --save mysql2

$ npm install --save-dev sequelize-cli

// 프로젝트 시작
$ npx sequelize-cli init



Migration

Migration은 개별 SQL 파일을 MySQL 콘솔 등에서 직접 실행하지 않고, 프레임워크의 특정명령어를 통해 실행하고 이 결과를 별도의 테이블에 버전 관리를 하는 기법이다.

// urls 테이블 생성
$ npx sequelize-cli model:generate --name urls --attributes (이어서)
name:string, email:string, phoneNumber: integer



👉 Controller 작성 및 Router 연결


controll


Sequelize 예제 (SELECT *)

models.findAll()
  .then(results) {
     res.json(results);
  })
  .catch(err => {
     console.error(err);
  });


Sequelize 예제 (UPDATE)

models.update({ visits: models.visits + 1 }})
  .then(result => {
     res.json(result);
  })
  .catch(err => {
     console.error(err);
  });


Sequelize 예제 (INSERT)

models.create({ url: 'www.github.com', title: 'github' })
  .then(result => {
     res.json(result);
  })
  .catch(err => {
     console.error(err);
  });


위에 내용들을 토대로 오늘 get 요청과 post 요청, 그리고 redirection을 구현했다.

const models = require('../../models').url;
const {  getUrlTitle } = require('../../modules/utils');

module.exports = {
    get: async (req,res) => {
        // Sequelize는 Promise 객체로 리턴하며, get 요청을 해준다.
        const urls = await models.findAll();
        res.status(200).send(urls)
    },

    redirections: async (req, res) => {
        const id = req.params.id;
        // 방문한 url을 count 해주어야 한다.
        const dbData = await models.findOne({
            where: { id },
        }).then((result) => {
            // 해당 데이터를 업데이트한다.
            return result.update({ visits: result.visits + 1 });
        }).then((result) => {
            // 해당 url 필드값으로 리디렉션한다.
            return res.redirect(result.url);
        });
    },

    post: (req, res) => {
        const url = req.body.url;
        getUrlTitle(url, async (err, title) => {
            // 데이터를 추가한다.
            const model = await models.create({ url, title });
            res.status(201).send(model);
        })
    }
}


Router

위에 Controllers 를 구현한 후에 Router 파일에서 라우팅을 해주었다.

// routes/links.js
const express = require('express');
const router = express.Router();
const controllers = require('../controllers/links/index');

router.get('/', controllers.get);
router.post('/', controllers.post);
router.get('/:id', controllers.redirections);

module.exports = router;









🙌 느낀점


이렇게 MVC 패턴에 대해서 공부를 하게 되었다. 오늘 만났던 페어분이 데이터베이스쪽으로 공부를 하다가 오신 분이셔서 생각보다 문제들을 잘 풀어나갈 수 있었다. 결국은 모든 구현 문제를 공식문서만 보고 풀었다. 그러다보니 중간에 잠깐 막혔던 부분도 있었는데, 그럴때마다 서로 물어봐가면서 하다보니 잘 해결할 수 있었다.

오늘 처음 배운 ORM을 아직 익숙하지 않은 MVC 패턴에 적용을 하다보니 많이 어색하고 중간중간 어려웠던 부분도 많았다.

그래도 정해진 시간보다 빨리 해결하고 시간도 많이 남아서 좋았다.

내일은 Mongo DB를 혼자 공부해보는 시간을 가진다. 내일도 잘 해결해나아갔으면 좋겠다.





👊 내일의 TIW(today I Will)

Mongo DB