09/08, ORM, Shortly.mvc(2)

Ian·2020년 9월 8일
0

Today I Learned

목록 보기
21/40

Sprint - part.2

MVC 에 맞춰서 controller 구현하기

MVC 패턴에서 controller 는 view 와 model 의 중간에서 정보를 적절히 가공하여 넘겨주는 역할을 한다. 그렇다는 건 view 를 통해 어떤 input 이 들어온다면 controller 가 그걸 받아 처리하고, model 에 넘겨줘야 한다. 또, 어어떤 값을 불러와야 하는 경우 model 은 controller 에게 값을 전달하고, 마찬가지로 controller 는 그 값을 model 에서 render 하기 편하게 가공한 뒤, 그걸 view 로 전달한다.

module.exports = {
    get: () => {
        console.log(a);
    },
    post: () => {
        console.log(b);
    }
}

일단은 이런 식으로 skeleton 만 짠 다음, model 을 비롯한 나머지들과 같이 생각해 보기로 했다.

Router 연결

이제 express 로 구현된 router 와 내가 만든 controller 를 연결해야한다. 일단은 module.exports 로 내보내진 router 를 구현한 JS 파일을 require 를 통해 불러와 주고 callback 으로 활용, controller 안에 그 response 혹은 request 를 인자로 넘겨줄 생각이다.


Office Hour

sequelizer 의 장/단점

장점

  • 여러 DBMS 에 대응할 수 있다

단점

  • 아무래도 직접 쿼리를 보내는 게 아니라, 하나의 layer 를 거쳐야 하기 때문에, 조금 느리다
  • 복잡한 쿼리문을 보내야 할 때 callback hell 이 생겨버릴 수 있다 (Promise 기반)

DML / DDL

DML

Data Manipulation Language 의 약자, 한 글자로 말하자면 "조작어". INSERT, UPDATE, SELECT, DELETE 등이 있다.

DDL

Data Definition Language 의 약자 CREATE TABLE 등이 있다.

Sequelize 직접 시작해보기

그 이전에 morgan 에 대해서 이야기하자면, 어떤 요청이 들어왔는지 간단하게 로깅해주는 그런 패키지이다.

seeder 라는 개념에 대해서...

DB를 구축한 다음 집어넣는 데이터셋을 의미함. model 의 default value 랑은 좀 다르다. 그건 값이 입력이 안 되면 해당 기본값으로 넣는다는 의미이고, seeder 는 거기에 실제로 들어가는 Records 들이다.

model:create 을 할 때...

attribute 에서 , 뒤에 띄어쓰기를 넣어주고 싶으면 "" 으로 묶어줘라.

model 과 migrations

model 은 클래스, migrations 는 인스턴스와도 같은 역할이다. model 은 직접 DB를 어떻게 변경할지가 담겨있다. migrations 는

model은 view 와 소통, migration은 db와 소통

모델에서만 defaultValue를 설정해주면 데이터베이스 자체에는 default가 없지만
model에서 애초에 해당 field에 값이 없으면 default로 바꿔서 보내주게됩니다.

updatedAt, createdAt 을 사용하기 싫다면?

option 에서 timestamp: false 등으로 명시해주어야 한다.

제대로 바꿔주려면, model 과 db를 전부 변경해주어야 한다.

model 은 클래스 생성자, migration 은 내가 실제로 사용하는 DB

그래서 model 이 view 이고, migration 이 DB 라는 거구나!

mysql 과 mysql2 의 차이

mysql 은 직접 쿼리를 발송하기 위해서, mysql2 는 ORM 을 위한 dependencies 같은 느낌...


Sprint - part 2 (오후)

질문에 답해보기

ORM 은 이 중에서 어떤 역할을 하고 있을까? → ORM 중 우리가 만든 model 은 DB의 역할을, 그리고 그 model 로 만든 instance 격의 migration 은 model 의 역할을 한다.

controller 구현

지금 만드는 건 url shortener 이기 떄문에, 이제 endpoint 로 날아오는 요청의 body 에 있는 url 정보를 받아야 한다. 그 url 정보로 사이트의 제목을 크롤링하여 title 이라는 column 에 할당하고, visit 은 +1 을 해주고, 그런 식으로 DB에 records 를 만들어준다.

일단 간단하게 구현을 해 봤는데, bootstrapping 으로 만든 model-migration 에다가 내가 만든 query 를 발송하는 과정에서 조금 막히고 있어서 구글링을 해 보는 중이다.

module.exports = {
    get: () => {
        return 'request get okay';
    },
    post: async (postURL) => {
        // url 을 받아서 해야 할 일
        // 1. db에 record 를 추가한다, 개형은 아래와 같다.
        // {
        //     "id": 자동생성,
        //     "url": url,
        //     "title": titleCrawler(url),
        //     // callback 에 담겨나오는 형식임, callback 을 인자로 넣어줘서 제목을 받아야 한다.
        //     "visits": db.visits + 1
        //     // 기존 db에 있던 값에 1을 더해서 다시 할당
        // }
        let newURL = await url.create({
            url: postURL,
            title: titleCrawler(postURL, (err, title) => {
                if (err) {
                    return err;
                } return title;
            }),
            visits: Model.findAll({
                attributes: ["visits"]
            }) + 1
        })
    }
}

연결하기

나는 현재 url 이라는 model 을 만들었고, 그것으로 migration 을 만들어서 urls 라는 테이블이 존재한다. 현재 작업하는 영역은 development 환경. 이제 controller 를 비롯한 영역들을 url 의 urls 라는 table 과 연결하면 된다.

삽질

scope 관련해서 이번에도 자꾸 골머리를 싸매다가 이제서야 해결했다.

module.exports = {
    get: () => {
        return 'request get okay';
    },
    post: (postURL) => {
        // url 을 받아서 해야 할 일
        // 1. db에 record 를 추가한다, 개형은 아래와 같다.
        // {
        //     "id": 자동생성,
        //     "url": url,
        //     "title": titleCrawler(url),
        //     // callback 에 담겨나오는 형식임, callback 을 인자로 넣어줘서 제목을 받아야 한다.
        //     "visits": db.visits + 1
        //     // 기존 db에 있던 값에 1을 더해서 다시 할당
        // }
        titleCrawler.getUrlTitle(postURL, (err, title) => {
            if (err) {
                throw err;
            }
            db.create({
                url: postURL,
                title: title,
                // visits: Model.findAll({
                //     attributes: ["visits"]
                // }) + 1
                visits: 0
            })
            returnVal = "nice post request"
        })
     
        return returnVal
    }
}

원래 코드는

module.exports = {
    get: () => {
        return 'request get okay';
    },
    post: (postURL) => {
        // url 을 받아서 해야 할 일
        // 1. db에 record 를 추가한다, 개형은 아래와 같다.
        // {
        //     "id": 자동생성,
        //     "url": url,
        //     "title": titleCrawler(url),
        //     // callback 에 담겨나오는 형식임, callback 을 인자로 넣어줘서 제목을 받아야 한다.
        //     "visits": db.visits + 1
        //     // 기존 db에 있던 값에 1을 더해서 다시 할당
        // }
        let urlTitle = titleCrawler.getUrlTitle(postURL, (err, title) => {
            if (err) {
                throw err;
            }
						return title;
        })
				db.create({
					url: postURL,
					title: urlTitle,
					// visits: Model.findAll({
					//     attributes: ["visits"]
					// }) + 1
					visits: 0
				})
    }
}

와 같은 코드였는데, 자꾸 urlTitle 이라는 변수를 db.create 에서 참조하지 못 해, 그냥 위처럼 titleCrawler.getUrlTitle 로 불러오는 과정 안에 넣어버렸다. 사실 이것도 일부 레퍼런스 코드를 참조하여서 겨우 생각해낸 방법이다. 참... 이번에도 완성하지 못 하고 이렇게 마무리한다니. 슬프다. 시간이 너무 늦어서 여기까지 공부를 마무리하고 씻고 자야겠다.


Nested Concepts

Warning: Accessing non-existent property 'shortener' of module exports inside circular dependency
POST /links 500 14.567 ms - 4358

Sequelize

여기서 incrementing and decrementing integer values 라는 단락을 통해 굳이 재할당 할 필요 없이 쿼리를 날려줄 수 있을 듯 하다.

profile
правда и красота, truth and beauty

0개의 댓글