ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • MVC 파트, Short.ly
    Topic/Database 2022. 1. 26. 19:41
    반응형

    Short.ly MVC ✔️

    어떤 url 주소를 짧은 url 주소로 변환하여 주는 역할을 해주는 어플리케이션을 가지고 mysql, MVC 다뤄본다.

     

    1) controllers 디렉토리 생성

    models, routes, modules 등의 디렉토리 들과 동일 선상에 controllers 디렉토리를 생성해 주고,
    그 안에 links 라는 디렉토리를 생성한 후, links안에 index.js 생성

    controllers / links / index.js

     

    2) app.js

    서버 통신을 위한 express 와 routes 디렉토리 내에 있는 라우팅 파일들을 불러와서

    app.use('/', indexRouter)
    app.use('/links', linksRouter)

    클라이언트가 해당 경로로 요청을 보냈을 때 indexRouter 와 linksRouter를 실행시킨다.

     

    3) routes/links.js

    index.js 와 links.js 이 두 파일이 있는데 index 파일은 이미 작성되어 있기 때문에 links.js 내 코드를 작성했다. 👇🏻

    const express = require('express')
    const router = express.Router()
    
    const linkController = require('../controllers/links')
    
    /* GET links listing. */
    router.get('/', linkController.get)
    
    router.post('/', linkController.post)
    
    router.get('/:id', linkController.redirect)
    
    module.exports = router

    라우팅 해주는 파일에서는 컨트롤러의 파일을 (기본 index 파일을) 불러오게 작성하고,
    linkController index.js 에 들어가면 get, post, redirect 함수가 구체적으로 작성되어 있음을 알 수 있다.

    controllers의 역할은 즉, 함수라는 것이 동작하는 기능을 수행하기 위해 만들어 졌으니까 get, post, redirect 가 구체적으로 어떤 역할을 하는지 어떤 동작을 하는지 정의하는 것?!

    그리고 어떤 특정 페이지를 접속할 때 해당 페이지를 다시 리다이렉션

    //router 에 :id 이렇게 경로가 입력되면
    router.get('/:id', linkController.redirect)
    
    //" /: " 이거는 req.params 이다.

    /:id 에서 /: === req.params
    /:id === req.params.id

    * 리다이렉션도 get 방식으로 가져온다는 것!

     

    4) modules/utils.js

    getUrlTitle 이라는 함수가 정의됨과 동시에 export 되어 있다.
    url 주소에서 meta 태그 중 title 이라는 것의 알맹이를 뽑아 오는 기능인가?

    이것은 controllers 에서 사용될 것!

     

    컨트롤러 역할을 하는 파일에서 해당 (url) models 를 불러와야지,
    models 에서 controller 를 참조하게 하면 MVC 패턴에 어긋난다고 한다.
    그래서 models 의 url model 을 불러오고
    modules 내 utils 도 동일하게 불러왔다.

    const utils = require('../../modules/utils')
    const { url } = require('../../models')
    // const Url = require('../../models').url 로 써줄 수도 있다.
    
    module.exports = {
      get: (req, res) => {
        // get method
      },
      redirect: (req, res) => {
        // redirect method
      },
      post: (req, res) => {
        // post method
      },
    }

    공식 문서 https://sequelize.org/master/manual/model-querying-finders.html 참고

     

    Manual | Sequelize

    Model Querying - Finders Finder methods are the ones that generate SELECT queries. By default, the results of all finder methods are instances of the model class (as opposed to being just plain JavaScript objects). This means that after the database return

    sequelize.org

     

    5-1) urls 의 테이블 모든 내역 다 불러오기 (GET)

    SELECT \* FROM urls

    이 SQL 문을 sequelize 으로 표현하라는 거다.

     

    방법 1 : .then 으로 이어 붙이기

    module.exports = {
      get: (req, res) => {
        // SELECT * FROM urls
        url.findAll().then(data => res.status(200).json(data))
      },
    }

    get 만 작성하고 콘솔 로그를 하면 빈 배열이 나오고, 모든 코드를 작성한 뒤 찍어보면 data 의 모습은 아래와 같이 나오게 된다.

     [
      url {
        dataValues: {
          id: 4,
          url: 'https://www.github.com',
          title: 'GitHub: Where the world builds software · GitHub',
          visits: 2,
          createdAt: 2020-12-07T12:12:34.000Z,
          updatedAt: 2020-12-07T12:23:48.000Z
        },
        _previousDataValues: {
          id: 4,
          url: 'https://www.github.com',
          title: 'GitHub: Where the world builds software · GitHub',
          visits: 2,
          createdAt: 2020-12-07T12:12:34.000Z,
          updatedAt: 2020-12-07T12:23:48.000Z
        },
        _changed: Set {},
        _options: {
          isNewRecord: false,
          _schema: null,
          _schemaDelimiter: '',
          raw: true,
          attributes: [Array]
        },
        isNewRecord: false
      },
      url {
        // 다음 id 의 데이터 value 가 들어온다.
      }, ......

     

    방법 2 : async 와 await 을 사용하기

    공식문서 코드를 찾아 테스트해보았다.
    but, post 와 redirect 작성 전에는 맨 아래 console.log 는 빈 배열만을 나타낸다.

    module.exports = {
      get: async (req, res) => {
        let allUrlLink = await url.findAll()
        console.log(allUrlLink.every(one => one instanceof url))
        res.status(200).json(allUrlLink)
        console.log('All URL Link here --->>>>>>>', JSON.stringify(allUrlLink)) // 빈배열..
      },
    }

     

    5-2) url 테이블에 값 넣어보기 (POST)

    방법 1. .then 사용하기

    utils.js 를 들어가 보면 해당 url 사이트의 메타 정보 title 코드가 있다.
    첫 번째 인자: url 을 받고 두 번째 인자: 콜백 함수를 받는다.

    console.log(req.body)
    // { url: 'https://www.github.com' } 가 나온다.
    module.exports = {
      post: (req, res) => {
        utils.getUrlTitle(req.body.url, (err, title) => {
          url
            .create({
              url: req.body.url,
              title: title,
            })
            .then(data => res.status(201).json(data))
        })
      },
    }

     

    방법 2. async, await 사용하기

    module.exports = {
      post: async (req, res) => {
        utils.getUrlTitle(req.body.url, async (err, title) => {
          let result = await url.create({
            url: req.body.url,
            title: title,
          })
          res.status(201).json(result)
        })
      },
    }

     

    6) redirect 작성하기

    GET /links/:id
    
    status code: 302 (성공적으로 리디렉션했을 시)
    해당 id 값 바탕으로 url 모델을 찾아 리디렉션합니다.
    원본 URL이 https://www.github.com 인 모델 id가 1일 경우
    http://localhost:3000/links/1 로 접속하면 원본 URL로 리디렉션
    /links/:id URL로 접근할 경우 visits 필드에 카운트가 1씩 증가해야 합니다.

     

    UPDATE urls SET visits = visits + 1 WHERE id = req.params.id

    접속한 url 파라미터가 ”/:” -> req.params

     ”/:id” 는? req.params.id //

     

    방법 1 : .then 으로 이어 붙이기

    module.exports = {
      redirect: (req, res) => {
        url.findOne({ where: { id: req.params.id } }).then(data => {
          url.update({ visits: data.visits + 1 }, { where: { id: req.params.id } })
          res.redirect(data.url)
          res.status(302).send()
        })
      },
    }
    {
      where: {
        id: req.params.id
      }
    }

     

    방법 2 : async, await 을 사용하기

    module.exports = {
      redirect: async (req, res) => {
        // update urls SET visits = visits + 1 where urls.id = 찾는값;
        let result = await url.findOne({ where: { id: req.params.id } })
        url.update({ visits: result.visits + 1 }, { where: { id: req.params.id } })
        res.redirect(result.url)
        res.status(302).send()
      },
    }

     


     

    반응형
Designed by LEO.