코드스테이츠 12주차 / Short.ly MVC(part 2)

나머지 테스트케이스를 통과해보자!!

1) controller 작성

테스트케이스에 가보면 파일이 존재해야 하는 위치를 알려주고있다
이대로 폴더, 파일을 작성해주자

  it('links controller 파일이 존재해야 합니다', () => {
    let hasLinksController = fs.existsSync('./controllers/links/index.js');
    expect(hasLinksController).to.be.true;
  });

controllers/links/index.js

get과 post메소드가 존재해야 한다고 했기 때문에 일단 메소드를 작성해주자
메소드 작성 방법은 어제 풀었던 Cmarket Database 의 controllers -> index.js 참고 !

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

2) router 연결

POST /links는 links controller의 post 메소드를 실행합니다
GET /links는 links controller의 get 메소드를 실행합니다

const express = require('express');
const router = express.Router();
const linksController = require('../controllers/links')

/* GET links listing. */
router.get('/', linksController.get);
router.get('/:id', linksController.redirect);
router.post('/', linksController.post);


module.exports = router;

아까 작성했던 컨트롤러를 linksController라는 변수로 선언 해주고 연결을 해주면 된다

그리고 일단 응답을 해주게 되면 테스트 케이스가 통과한다

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

3) controller 구현

이제 응답만 해줬던 컨트롤러를 구현해보자

유어클래스에서 endpoint에 대한 API를 알려주고 있으니 참고해서 작성하면 된다

3-1) POST /links

post 요청은 req.body에 url을 담아 요청하는데
요청받은 url이 기존 데이터베이스에 저장되어있던 url이라면 저장된 url을 반환하고
요청한 url이 존재하지 않는다면(처음 요청한 url) 데이터베이스에 해당 url 정보를 저장, 201을 리턴한다

findOrCreate

url 이 있는지 확인하고 없을 경우 생성하는 findOrCreate 메서드를 사용
찾는 값을 where에 없을 경우에 생성할 값을 defaults에 작성
const [url, created] = await model.url.findOrCreate({where:{}, defaults:{}})
[url, created] 이렇게 배열 형태로 리턴 하는데 첫번째 인자가 내가 조회한,생성한 결과물 , created가 true 라면 findOrCreate를 통해서 url 생성했다 / created가 false 라면 이미 결과물이 있어서 그냥 조회했다고 알려준다
Model Querying - Finders

const model = require('../../models')
// 모델을 사용해야 한다 
// models > index.js -> module.exports = db; db객체가 불러와진다

// models > index.js 파일은 모델을 생성하고 난 다음 파일시스템으로 읽어오는 역할을 한다 
// 모델이 하나가 아닐 수도 있으므로 url모델, class모델 등등 
// 이걸 직접 전부 읽어오는게 아니라 index.js에서 전부 읽어와서 모델안에 해당하는 필드 값으로 존재할 수있게 해준다
const {getUrlTitle, isValidUrl} = require('../../modules/utils')

module.exports = {
  post: (req, res) => {
    // req.body.url을 데이터베이스에 있는지 확인한다
    // 없을경우 새로 생성
    // 원본 url로 get 요청을 보내서 title태그 사이의 값을 얻어온다  --> modules/utils.js 에 정의되어 있다 
    // url 테이블의 title, url값을 저장한다 
    // 성공시에 방금 생성한 모델을 json 형태로 전송한다 
    const originUrl = req.body.url;
    if(!isValidUrl(originUrl)){
      return res.sendStatus(400);
    }
    getUrlTitle(originUrl, async (err, result)=>{
      if(err){
        return res.sendStatus(500);
      }
      const [url, created] = await model.url.findOrCreate({
        where: {
          url: originUrl,
        },defaults:{
          title: result, // getUrlTitle이 실행되면서 title을 얻어온 결과물을 넣어주면 된다
        }
      });
      if(created) {
        return res.status(201).json(url); // 생성
      }
      return res.status(201).json(url); // 조회
    });
  }
}

3-2) GET /links

Model Querying - Finders

const model = require('../../models')

const {getUrlTitle, isValidUrl} = require('../../modules/utils')

module.exports = {
  get: async (req, res) => {
    // url테이블의 전체 목록을 json으로 보내준다 
    const result = await model.url.findAll();
    if(!result){
      return res.sendStatus(204);
    }
    res.json(result);
  }
}

3-3) GET /links/:id

const model = require('../../models')
const {getUrlTitle, isValidUrl} = require('../../modules/utils')

module.exports = {
  redirect: async (req, res) => {
    const urlId = req.params.id;
    // urls 테이블에 urlId를 pk로 가진 레코드를 찾고 -> findByPk
    // 해당 레코드의 visits 필드의 값을 1 증가 -> update
    // 조회한 레코드의 url값으로 리디렉션 한다 
    const result = await model.url.findByPk(urlId); 
    await result.update({
      visits: result.visits + 1 
    })
    const redirectUrl = result.url;
    return res.redirect(redirectUrl)
  }
}

Model Querying - Finders

Model Querying - Basics

express redirect

좋은 웹페이지 즐겨찾기