11월 28일 (일) MVC (ORM, Sequelize) _ (수정 필요)

남이섬·2021년 11월 28일
0
post-custom-banner

본 스프린트는 Bitly 서비스 과정을 생각하면서 풀어본다
(url 축약 서비스)

스프린트 과정

1. POST /links은 url을 받아 단축 url로 만든다

Controller

  • POST 요청이 들어온다
  • 축약하려는 url이 기존 DB에 있는지 확인
  • GET 요청을 통해 원본 URL 접속
  • <title> 태그의 내용을 가져온다
  • 새로운 레코드를 만든다 (원본 url, 타이틀)
  • 새 레코드의 ID가 접속 방법이 된다

Model (상태를 나타내는 프로퍼티 / 동작을 나타내는 메서드)

  • 기존 DB에 있는지 확인
  • 새로운 레코드를 만든다
  • 새 레코드의 ID

2. GET/links는 urls 테이블의 목록을 JSON의 형태로 반환한다

Controller

  • GET 요청이 들어온다
  • 라우터를 통해 links 컨트롤러로 분기
  • 데이터베이스에서 urls 테이블 조회
  • json으로 데이터 전송

Model

  • 데이터베이스에서 urls 테이블 조회

3. GET/links/:id을 요청하면 url 필드값으로 리디렉션 한다

Controller

  • GET 요청이 들어온다
  • 라우터를 통해 links 컨트롤러 분기
  • 데이터베이스에서 urls 테이블 조회
    • url 파라미터
  • Visits 필드의 값 1 증가
    • Visits, 방문 횟수를 증가 시며주는 이유
      (url 축약으로 사람 방문횟수를 기록하면 얼마나 비지니스 효과가 있는지 파악 할 수 있다)
  • 해당 url로 리디렉션
    • 리디렉션 이란
      (해당 url로 즉 축약한 url로 안내 하는 것)

Model

  • 데이터베이스에서 urls 테이블 조회
  • Visits 필드의 값 1 증가

Sequelize 설정 후
시퀄라이즈에서 CRUD(Create, Read, Update, Delete) 작업은 sql문을 자바스크립트를 통해 만든다

쿼리는 프로미스를 반환하므로 then이나 async/await문법으로 다룰 수 있다

Controller 작성 및 Router 연결

1. 웹 개발에 있어서 라우터는 컨트롤러로 진입할 수 있게 도와주는 endpoint

라우터에 컨트롤러를 연결해야 한다
예를 들어 /links URL로 GET 또는 POST 요청을 보낼 경우, links 컨트롤러의 메소드가 실행되도록 만들 수 있다

controller/links/index.js

module.exports = {
  get: async (req, res) => { },
  post: async (req, res) => { }
}

레코드를 조회하기 위해선, findOne, findAll 메서드를 사용한다

  • 모든 데이터 findAll
  • 하나의 데이터 findOne

2. router 연결 (routes/links.js)

routes/links.js에서 endpoint에 따라서 get, post요청 분기

const linksController = require('../controller/links')

controller를 require로 가져온 이유는 require가 객채를 반환 하기 때문에 사용.

const express = require('express');
const router = express.Router();

const linksController = require('../controller/links')

router.get('/', linksController.get)
router.get('/:id', linksController.get)
router.post('/', linksController.post)

module.exports = router;

router와 controller를 연결 하면 req를 받아 올 수있다

req.body

{ url: 'https://www.github.com' }

console.log에 req.body를 찍었을때 url이 깃헙 주소가 나오는 이유는 test에 명시 되어 있어서 그런거 같다

3. POST 요청을 구현할 때, 웹사이트의 제목을 가져오기 위해 modules/utils.js를 이용할 수 있다

상기의 이미지와 같이 urls table의 url, title 필드에 값들을 저장 해야 한다

url 가져오기

POST method는 데이터를 서버로 전송한다
즉, request body에 url이 담겨져 있다

title 가져오기 및 url 비교

modules/utils.js

const request = require('request');

const rValidUrl = /^(?!mailto:)(?:(?:https?|ftp):\/\/)?(?:\S+(?::\S*)?@)?(?:(?:(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[0-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]+-?)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]+-?)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})))|localhost)(?::\d{2,5})?(?:\/[^\s]*)?$/i;

exports.getUrlTitle = (url, cb) => {
  request(url, function (err, res, html) {
    if (err) {
      console.log('Error reading url heading: ', err);
      return cb(err);
    } else {
      const tag = /<title>(.*)<\/title>/;
      const match = html.match(tag);
      console.log(match.length)
      const title = match ? match[1] : url;
      return cb(err, title);
    }
  });
};

exports.isValidUrl = url => {
  return url.match(rValidUrl);
};

modules/utils.js 파일 안을 보면 title태그를 가져오는 것을 볼수 있다

MYSQL

요청 바디 url이 table에 url이 있는지 없는 지 확인
url이 없다면 title 등록

const queryString = `SELECT urls.title FROM urls where urls.urls = ${req.body.url}`

if (queryString) {
  const queryString = INSERT INTO urls (url, title)
  db.query(queryString, (err, result) => {
    callback(err, result)
  })
}

쿼리문이 맞는지 모르겠다 (연습 필요)

ORM



## 4.GET 요청

> **controllers/links/indes.js**

const { url: urlModel } = require('../../models')

url의 변수명을 urlModel로 변경



> **SELECT * FROM urls**

module.exports = {
get: async (req, res) => {
const result = await urlModel.findAll()
res.status(200).json(result)
}
}














profile
즐겁게 살자
post-custom-banner

0개의 댓글