Sprint - Sequelize/Shortly-mvc

seungmini·2021년 7월 29일
2

스프린트

목록 보기
1/1

1. Sequelize 가 무엇인가?

이것이 공식문서에 기재되어 있는 Sequelize 프로그램의 정의입니다, 직역한다면

Sequelize는 Postgres , MySQL , MariaDB , SQLite 및 Microsoft SQL Server 용
약속 기반 Node.js ORM 입니다 . 견고한 트랜잭션 지원, 관계, 열망 및 지연 로딩, 읽기 복제 등을
제공합니다.

이란 뜻으로 해석되는데, 쉽게 말하자면 Promise 기반의 Node.js ORM 으로서 우리가 사용하는
MySQL 을 위한 프로그램이라고 합니다.

여기서 ORM 이란것은 Object Relational Mapping 의 약자로 객체지향 언어에서 관계형 데이터베이스에
접근이 가능하도록 도와주는 중간다리의 역할을 한다고 보면 되겠습니다.

2. Sequelize 설치

Sequelize 공식문서 : https://sequelize.org/master/index.html

공식문서를 참고하고, 설치를 위한 명령어를 터미널에서 입력을 해줍니다.

명령어를 입력하고 해당 프로젝트의 pakage.json 파일을 확인해봅시다.
Sequelize의 최신버전이 다운로드 된것을 확인할 수 있을겁니다.

3. Sequelize - cli 설치

이번에는 Sequelize - cli 을 설치하겠습니다.

Sequelize - cli 는 뭔가요?

학원에서 제공하는 설명으로는 Sequelize - cli 가 마이그레이션을 할 수 있도록 돕는 툴로,
CLI에서 모델을 생성해주거나 스키마 적용을 할 수 있도록 돕는다고 합니다.

추가로 공식문서를 인용하여 설명을 해보자면

음.. 뭐 대충 이렇다고 합니다, 찬찬히 읽어보시길... 자, 이제 설치해줍시다.

이렇게 입력을 해주고 나면 package.json 파일의 devDependencies 목록에
sequelize-cli가 생성됬을겁니다.

4. Sprint 초기단계 설정

프로젝트의 기본설정을 해봅시다.

1) Bootstapping

3번의 sequelize - cli 까지 설치를 마쳤다면, 위의 명령어를 입력하여 기본 폴더를 생성해 보겠습니다.
총 4가지의 폴더가 생성될겁니다.

1) config: CLI에게 어떻게 데이터베이스와 연결할 지 알려주는 config file을 지닌 폴더

2) models: 프로젝트에 쓰일 모든 model을 지닌 폴더

3) migrations: 모든 migration file을 지닌 폴더

4) seeders: 모든 seed file을 지닌 폴더

2) Configuration

이것은 CLI 와 데이터베이스의 연결을 위해 필요한 파일입니다, config폴더에 있는 config.json 파일을 열면
아래의 그림과 같은 모습을 볼 수 있을겁니다.

총 세개의 데이터베이스가 존재하는데 각각 개발, 테스트, 배포용 이라는 의미를 가지고 있습니다.
우리는 기본적으로 development 즉, 개발용 데이터베이스를 쓰고있는데 그 이유는 models 폴더의
index.js 파일을 보면 알 수 있습니다.

7번째 줄을보면 변수 env 는 다른값이 주어지지 않으면 기본값으로 'development' 를 가지고 있습니다.
따라서 우리가 여기서 다른 데이터베이스를 선택하지 않으면 기본값인 'development' 가 설정이 됩니다.

config.json 에서는 데이터베이스의 이름과 비밀번호정도를 변경해 주도록 합니다.
(각자의 데이터베이스 환경에 따라 알아서 작성하세요)

5. First Model 및 Migration 생성하기

첫 모델과 마이그레이션을 생성해 봅시다. 공식문서를 참조합니다.

공식문서에 쓰여진 대로라면, 우리는 이 명령어를 입력하고 실행한 뒤에
models 폴더에 user 라는 파일이 생성될것이고, xxx-create-user 라는 파일이 migrations 폴더에
생성이 된다고 합니다, 이 명령어를 통해서 우리가 생성해야 하는 폴더와 파일을 만들어 보겠습니다.

스프린트에서는 url, title, visits 필드를 생성해야 한다고 합니다.
id, createdAt, updatedAt 필드는 자동적으로 생성된다고 하니, 우리가 생각해야 할것은 두가지 입니다.

  1. url 모델이 필요하다.
  2. url, title, visits 필드가 필요하다.
    -> url은 모델, 필드 두군데서 다 필요합니다, 중복된다고 혼동하지 마세요
npx sequelize-cli model:generate --name Url --attributesurl:string,title:string,visits:integer

이렇게 입력을하고 실행을 해봅시다, 어떤 결과가 나올까요?

migration 폴더와 models 폴더에 각각의 파일이 잘 생성된걸 확인할 수 있습니다.

6. Migration / Model 초기값 설정

1) Model 초기값 설정하기

테스트케이스 중에 visits 의 초기값이 0이어야 한다는 조건이 있죠.

이를 통과하기 위해서는 models 폴더의 url 파일을 수정해야 합니다.
만들어진 모델의 수정은 이곳에서 가능하다, migration 에서는 수정이 안되니 참고하길 바랍니다.

공식문서를 참조하여 초기값을 설정하는 형식을 체크합니다.

' defaultValue: value '의 형식을 띄고 있습니다, 그렇다면 이대로 따라해보겠습니다.
일단 models 폴더의 url 파일을 보겠습니다.

기존의 이 상태였던 코드에서 defaultValue: value 형식을 추가해주겠습니다.

우리가 필요한것은 visits 의 초기값은 0 이되는것이니 이렇게 변경해 줍니다.

그리고 테스트를 실행하면 통과하는것을 볼 수 있을겁니다.

2) 마이그레이션 실행하기

또 다른 테스트케이스에 '마이그레이션을 했다면, urls 테이블이 존재해야 합니다.'
라는 조건을 써놨을텐데 일단 마이그레이션을 실행해야 합니다.

이 또한 공식문서에 있으니 참조합니다.

위의 명령어를 입력하면 마이그레이션이 실행됩니다, 그리고 마이그레이션은 스키마가 변경될때 마다 실행해줘야
한다고 하니, 참고바랍니다.

저렇게 명령어를 입력하고 테스트를 돌리면 또 무난하게 테스트가 통과됩니다.

테이블이 잘 추가가 됬는지 확인해 보겠습니다, MySQL 로 갑니다.

데이터베이스를 선택하고 , 그 안의 테이블을 보면

urls 테이블이 생성된걸 볼 수 있습니다. 이렇게 테스트를 통과합니다.

7. Controller 만들기

1) 분기별로 라우팅하기

app.js 입니다. 이 파일안에서 분기별로 라우팅을 한 모습입니다.

14번째 줄처럼 url 에 / links 가 붙으면 linksRouter 로 이동하게 됩니다. 5번줄의 영향이지요.
links.js 를 살펴보겠습니다.

각 메소드와 url 별로 controller 객체에 있는 메소드를 이용하고 있습니다.
controller 객체를 쓰기 위해 controllers 폴더를 생성하고 그 안에 links 폴더를 만들어주고
그 안에 index.js 파일을 만들어줘야 합니다. 그 다음에 routes 폴더 안에 있는 link.js 파일과
index.js 파일을 연결시켜 주었습니다, 이제 index.js 파일에서 서버로 오는 각 요청마다
데이터베이스에서 어떻게 처리할지를 정하도록 해주었습니다.

2) controller 객체 만들기 / GET

controllers 파일 -> links 파일 -> index.js 순으로 들어와 export 할
controller 객체를만들어 주겠습니다.

스프린트에서 제시하는 기능은 이렇습니다,

  1. content-type 은 application / json 형식이다.
  2. status code 는 200 이다.
  3. 그리고 응답에는 URL 모델의 목록을 출력한다.

어떻게 하면 URL 모델의 목록을 가져올 수 있을까요?

일단 아까 정해준 모델명을 url 로 했기때문에 url 모델을 가져오기 위해서는 뒤에 ' .url ' 을
꼭 붙여줘야한답니다, 왜냐하면 바로 가져오기 위해서라고 합니다.

이런식으로 쓰이는 겁니다.

그리고 처음 공식문서에서 나온 sequelize 에 대한 정의를 살펴보면
"sequelize는 promise 기반의 Node.js ORM 이다." 라고 합니다. 그렇다면 우리는 이 코드를
비동기적으로 풀어내야 하기때문에 여기서는 async, await 를 사용할겁니다.

await model.findAll( )을 하게되면 비동기 적으로 findAll( )을 처리하고
그 결과를 변수 data에 할당하게 됩니다. 여기서 findAll( ) 메소드는 SELECT * FROM 과 같은
역할을 한다고 보면 됩니다, 따라서 위의 방식처럼 코드를 작성하면 urls 테이블의 모든 내용을 가져와
변수 data에 할당하게 될것입니다.

3) controller 객체 만들기 / POST

클라이언트가 보낸 요청의 body 객체 안에 url 이 들어 있습니다, 그 url 을 변수에 할당하고
유효한지 아닌지를 판단 후, 유효하다면 제목을 받아와서 status code 201과 함께 JSON 객체를
응답하겠습니다.

코드를 그대로 해석해서 나열해 보겠습니다. 일단 post 요청을 하는거구요, req 와 res 가 들어오네요.
그리고 일단 요청으로 들어온 request 의 body에서 url 객체를 받아오는 변수를 하나 만들어 주겠습니다.

isValidUrl( ) 이 url을 인자로 받았음에도 불구하고 false 값이 된다면 400코드를 응답한다.
false가 된다는건 url이 잘못되었거나, 아직 받지 못한것이겠죠,

이 isValidUrl( ) 은 util.js 에서 가져옵니다. 주어진 url로 HTTP 요청을 하는 역할을 합니다.

하지만 정상적으로 url이 들어와서 요청에 성공했다면 getUrlTitle( ) 메소드를 생성합니다.
여기서는 웹사이트의 제목을 가져올겁니다, 때문에 인자는 url 과 비동기적으로 생성되는
err, title 이 주어집니다.

만약 에러가 난다면 콘솔에 에러와 함께 400코드를 응답해주면 됩니다.
그러나 정상적으로 동작한다면 model.findOrCreate( ) 메소드를 실행합니다. 이 findOrCreate( )는
쿼리옵션을 충족하는 항목을 찾을 수 없는경우에 테이블에 새로운 항목을 생성합니다.
그리고 항목이 있던지 없던지 인스턴스와 함께 Boolean 값을 반환합니다.

이 Boolean 값의 역할은 인스턴스가 새로 생성된건지 아니면 원래 있던건지를 알려줍니다.

여기서는 result 가 인스턴스이고, created 가 Boolean 값입니다.

where은 항목을 찾을때 사용하는 것이고, defaults 은 찾는 항목이 없을때, (초기) 새로 인스턴스를 생성
하기위해 반드시 넣어야 할 요소입니다.

만약 !created 이라면 이미 항목이 존재한다는 뜻이겠죠.
그렇다면 바로 인스턴스를 json 객체로 응답해주면 되겠습니다.
그리고 항목이 존재하지 않다면 위에서 url 에 해당되는 title 테이블을 만드는 겁니다.

이렇게 하면 모든 post 요청이 끝나게 됩니다.

3) controller 객체 만들기 / GET : id

마지막으로 요청받은 id 로 리디렉션을 하는 코드를 생성합니다.

리디렉션의 정의를 간단하게 설명하자면

라고 합니다, 쉽게 말해서 우리가 어떤 사이트를 들어갔을때, 그 사이트가 주소를 이전했거나 통합되었을때
사용자에게 url 주소를 알려줄수도 있겠지만, 바로 그 사이트로 이동하게끔 할 수 도 있는데.
이때 리디렉션을 이용합니다.

스프린트가 유도하는것은, 리디렉션이 성공하여 기존 우리의 로컬호스트 주소를 입력하면
로컬호스트가 아니라 깃허브의 홈페이지가 뜨게 하는걸 목적으로 하고 있습니다.

그것을위한 사이트 등은 이미 구현이 되어 있으니 우리는 그것을 연결해주는 코드만 작성하면 됩니다.

아까 맨처음 라우팅을 위해 방문했던 links.js 에서 한 줄을 더 추가해주겠습니다.

get 과 post 밑에 redirect 를 불러오는 get 요청을 하나 더 만듭니다, 이 요청은 id 값을 받았을때
실행됩니다. 자 이제 다시 돌아와서 redirect를 만들어보겠습니다.

일단은 id가 1인경우를 찾습니다, findOnd( ) 은 테이블의 첫번째 객체를 찾아서 반환하는 역할을 합니다.
그렇기때문에 이것을 이용하여 req.params.id 를 찾아 그 첫번째 객체를 받아오겠습니다.
그리고 이것은 곧 result가 됩니다.

then으로 연결을 해주고 결과값 result 가 정상적으로 들어왔을겨우, 결과값을 업데이트 하는데요.
무엇을? 바로 result의 visits 값을 요청이 들어올때마다 1이 증가하게 업데이트를 해주는겁니다.

스프린트에서 원하는것 중 하나죠. 완성했습니다.
그리고 result 가 들어오지 않았다면 204에러를 응답해주면 되겠습니다, 요청은 제대로 됬지만
컨텐츠를 제공하지 않는 오류죠.

그리고 마지막으로 리디렉션을 해주면 됩니다. 이것 또한 result 를 가지고 응답을 해주는데
무엇을 응답해주냐면, redirect( ) 메소드를 다시 실행시키는데, 이때 result.url 을 줍니다.
여기서 result가 의미하는 값은

바로 이 값이기 때문에, result.url 은 깃허브의 홈페이지가 됩니다. 그렇기 때문에 이제 로컬호스트
요청이 들어온다면 그 요청은 이제 깃허브로 리디랙션이 될겁니다.

자료출처:

profile
21.04 에 태어난 코린이

0개의 댓글