[shortly-mvc] Sequelize์™€ mvc์˜ ์ดํ•ด

์†์—ฐ์ฃผยท2021๋…„ 7์›” 28์ผ
0

SPRINT

๋ชฉ๋ก ๋ณด๊ธฐ
3/5
post-custom-banner

https://sequelize.org/
๐Ÿ“ ๊ณต์‹ ๋ฌธ์„œ๋ฅผ ํ†ตํ•ด ์Šคํ”„๋ฆฐํŠธ๋ฅผ ์ง„ํ–‰ํ•œ๋‹ค.
๐Ÿ“ ๊ณต์‹ ๋ฌธ์„œ ์ฝ๋Š” ๋ฒ•์„ ์ตํžŒ๋‹ค.

์™„์„ฑ๋œ urls ํ…Œ์ด๋ธ”์˜ ์Šคํ‚ค๋งˆ

mysql> describe urls;
+-----------+--------------+------+-----+---------+----------------+
| Field     | Type         | Null | Key | Default | Extra          |
+-----------+--------------+------+-----+---------+----------------+
| id        | int          | NO   | PRI | NULL    | auto_increment |
| url       | varchar(255) | YES  |     | NULL    |                |
| title     | varchar(255) | YES  |     | NULL    |                |
| visits    | int          | YES  |     | NULL    |                |
| createdAt | datetime     | NO   |     | NULL    |                |
| updatedAt | datetime     | NO   |     | NULL    |                |
+-----------+--------------+------+-----+---------+----------------+

Part 1 - Sequelize ๋ฐ CLI ๋„๊ตฌ ์ด์šฉ

์ด๋ฒˆ ์Šคํ”„๋ฆฐํŠธ๋Š” bitly ์ฒ˜๋Ÿผ ๊ธด url์„ ์งง๊ฒŒ ์ถ•์•ฝํ•ด์ฃผ๋Š” ์‚ฌ์ดํŠธ์˜ ๋กœ์ง์— ๋Œ€ํ•ด์„œ ํ•™์Šตํ•œ๋‹ค.

urls ๋ผ๋Š” ํ…Œ์ด๋ธ”์„ ๋งŒ๋“ค์–ด, ์›๋ณธ URL๊ณผ ๋‹จ์ถ• URL์˜ ๋ฐฉ๋ฌธ ํšŸ์ˆ˜๋ฅผ ๊ธฐ๋กํ•œ๋‹ค. SQL๋ฌธ์ด ์•„๋‹Œ ORM์„ ์ด์šฉํ•ด ์•„๋ž˜์™€ ๊ฐ™์€ ํ…Œ์ด๋ธ”์„ ๋งŒ๋“ ๋‹ค.

์‚ฌ์ „ ์ค€๋น„: sequelize ๋ฐ sequelize-cli ์„ค์น˜

 ๐Ÿš€ (1-1) ORM ์„ค์ •
    โœ“ cli๋ฅผ ํ†ตํ•ด ํ•„์š”ํ•œ ํŒŒ์ผ์ด ์ž๋™์œผ๋กœ ๋งŒ๋“ค์–ด์กŒ๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค
    โœ“ model/index.js ํŒŒ์ผ์ด ์œ ํšจํ•œ์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค
Executing (default): SELECT 1+1 AS result
    โœ“ mysql์— ์ ‘์†ํ•  ์ˆ˜ ์žˆ๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค (140ms)

1. sequelize ์„ค์น˜

sequelize๋Š” promise ๊ธฐ๋ฐ˜์˜ Node.js ORM์œผ๋กœ์„œ ์šฐ๋ฆฌ๊ฐ€ ์“ฐ๋Š” MySQL์„ ์œ„ํ•œ ํ”„๋กœ๊ทธ๋žจ์ด๋‹ค. ORM์€ Object Relational Mapping์˜ ์•ฝ์ž๋กœ ๊ฐ์ฒด ์ง€ํ–ฅ ์–ธ์–ด์—์„œ ๊ด€๊ณ„ํ˜• ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋„๋ก ๋„์™€์ฃผ๋Š” ์ค‘๊ฐ„ ๋‹ค๋ฆฌ ์—ญํ• ๋กœ ๋ณด๋ฉด๋œ๋‹ค. ์‰ฝ๊ฒŒ ๋งํ•ด ๋ฐ์ดํ„ฐ ๋ฒ ์ด์Šค์™€ ์†Œํ†ตํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค€๋‹ค.

๋ช…๋ น์–ด : npm i sequelize

2. sequelize-cli ์„ค์น˜

sequelize-cli๊ฐ€ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜์„ ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋•๋Š” ํˆด๋กœ, CLI์—์„œ ๋ชจ๋ธ์„ ์ƒ์„ฑํ•ด์ฃผ๊ฑฐ๋‚˜, ์Šคํ‚ค๋งˆ ์ ์šฉ์„ ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋•๋Š”๋‹ค๊ณ  ํ•œ๋‹ค. ๊ณต์‹๋ฌธ์„œ๋ฅผ ํ†ตํ•ด ์ข€ ๋” ์‚ดํŽด๋ณด์ž.

๋งˆ์ด๊ทธ๋ ˆ์ด์…˜์€ Git๊ณผ ๊ฐ™์€ ๋ฒ„์ „ ์ปจํŠธ๋กค ์‹œ์Šคํ…œ์ฒ˜๋Ÿผ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ์ถ”์ ํ•˜๊ณ  ์•Œ ์ˆ˜ ์žˆ๊ฒŒ ํ•œ๋‹ค. ๋˜ํ•œ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜์€ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ํŒŒ์ผ๋กœ์„œ ๋‘ ๊ฐœ์˜ ํ•จ์ˆ˜๋ฅผ ๋ฐ–์œผ๋กœ ๋‚ด๋ณด๋‚ด๋Š”๋ฐ ํ•˜๋‚˜๋Š” ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜์„ ์ˆ˜ํ–‰ํ•˜๋Š” up์ด๊ณ , ๋‹ค๋ฅธ ํ•˜๋‚˜๋Š” ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ์‹คํ–‰์„ ์ทจ์†Œํ•˜๋Š” down์ด๋‹ค.

๋ช…๋ น์–ด : npm i โ€”save-dev sequelize-cli

Project bootstrapping

1. Bootstrapping (์ดˆ๊ธฐ ๋‹จ๊ณ„ ์„ค์ •)

cli๋ฅผ ํ†ตํ•ด ORM์„ ์ž˜ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก bootstraping(ํ”„๋กœ์ ํŠธ ์ดˆ๊ธฐ ๋‹จ๊ณ„๋ฅผ ์ž๋™์œผ๋กœ ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋„์™€์ฃผ๋Š” ์ผ)์„ ํ•ด์ค˜์•ผ ํ•œ๋‹ค.

๋นˆ ํ”„๋กœ์ ํŠธ๋ฅผ ๋งŒ๋“œ๋Š” ๋ช…๋ น์–ด : npx sequelize-cli init

์ด ๋ช…๋ น์–ด๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ํด๋”๊ฐ€ ๋งŒ๋“ค์–ด์ง„๋‹ค.

1) config : ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์—ฐ๊ฒฐํ•˜๋Š” ๋ฐฉ๋ฒ•์„ CLI์— ์•Œ๋ ค์ฃผ๋Š” ๊ตฌ์„ฑ ํŒŒ์ผ์ด ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.
2) models : ํ”„๋กœ์ ํŠธ์˜ ๋ชจ๋“  ๋ชจ๋ธ์„ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค.
3) migrations : ๋ชจ๋“  ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ํŒŒ์ผ ํฌํ•จ
4) seeders : ๋ชจ๋“  ์‹œ๋“œ ํŒŒ์ผ์„ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค.

2. Configuration

๋จผ์ € cli์™€ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ์—ฐ๊ฒฐํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์•Œ์•„์•ผ ํ•œ๋‹ค.
config/config.json ํŒŒ์ผ์„ ์—ด๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋ณด์ธ๋‹ค.

{
  "development": {
    "username": "root",
    "password": null,
    "database": "database_development",
    "host": "127.0.0.1",
    "dialect": "mysql"
  },
  "test": {
    "username": "root",
    "password": null,
    "database": "database_test",
    "host": "127.0.0.1",
    "dialect": "mysql"
  },
  "production": {
    "username": "root",
    "password": null,
    "database": "database_production",
    "host": "127.0.0.1",
    "dialect": "mysql"
  }
}

3๊ฐœ์˜ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๊ฐ€ ์กด์žฌํ•˜๋Š”๋ฐ ๊ฐ๊ฐ ๊ฐœ๋ฐœ, ํ…Œ์ŠคํŠธ, ๋ฐฐํฌ์šฉ์ด๋ผ๋Š” ์˜๋ฏธ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ development ์ฆ‰, ๊ฐœ๋ฐœ์šฉ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ์“ฐ๊ณ  ์žˆ๋Š”๋ฐ models ํด๋”์˜ index.js ํŒŒ์ผ์„ ๋ณด๋ฉด ์•Œ ์ˆ˜ ์žˆ๋‹ค.

const env = process.env.NODE_ENV || 'development';

๋ณ€์ˆ˜ env๋Š” ๋‹ค๋ฅธ ๊ฐ’์ด ์ฃผ์–ด์ง€์ง€ ์•Š์œผ๋ฉด ๊ธฐ๋ณธ ๊ฐ’์œผ๋กœ 'development'๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค. ๋”ฐ๋ผ์„œ ์šฐ๋ฆฌ๊ฐ€ ์—ฌ๊ธฐ์„œ ๋‹ค๋ฅธ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ์„ ํƒํ•˜์ง€ ์•Š์œผ๋ฉด ๊ธฐ๋ณธ ๊ฐ’์ธ 'development'๊ฐ€ ์„ค์ •์ด ๋œ๋‹ค.

๋‹ค์‹œ config.json ํŒŒ์ผ๋กœ ๋Œ์•„์™€์„œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๋ช…๊ณผ ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅํ•ด ์ฃผ์—ˆ๋‹ค. ์ฐธ๊ณ ๋กœ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๊ฐ€ ์•„์ง ์กด์žฌํ•˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ db:create๋ช…๋ น์„ ํ˜ธ์ถœํ•˜๋ฉด ๋œ๋‹ค. ์ ์ ˆํ•œ ์•ก์„ธ์Šค๊ฐ€ ์žˆ์œผ๋ฉด ํ•ด๋‹น ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๊ฐ€ ์ƒ์„ฑ๋œ๋‹ค.

Creating the first Model (and Migration)

1. ๋ชจ๋ธ ์ƒ์„ฑ

CLI config file์„ ์ œ๋Œ€๋กœ ์„ค์ •ํ•˜์˜€๋‹ค๋ฉด ์ด์ œ ์ฒซ ๋ชจ๋ธ๊ณผ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜์„ ์ƒ์„ฑํ•ด์•ผ ํ•œ๋‹ค.

๋ชจ๋ธ ์ƒ์„ฑ
  โœ“ url ๋ชจ๋ธ์ด ์กด์žฌํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค
  โœ“ url ๋ชจ๋ธ์€ ์š”๊ตฌํ•˜๋Š” ํ•„๋“œ๋ฅผ ๊ฐ–๊ณ  ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค
  โœ“ url ๋ชจ๋ธ์˜ ๊ฐ ํ•„๋“œ๋Š” ์ •ํ•ด์ง„ ํƒ€์ž…์œผ๋กœ ์ƒ์„ฑ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค
  โœ“ url ๋ชจ๋ธ์˜ visits ํ•„๋“œ๋Š” ๊ธฐ๋ณธ๊ฐ’์ด 0์ด์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค

ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค์— ๋งž๊ฒŒ ์ž‘์„ฑํ•ด์ค€๋‹ค.

model:generate๋ช…๋ น์–ด๋ฅผ ํ†ตํ•ด ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค.

  • url, title, visits ํ•„๋“œ๋ฅผ ์ƒ์„ฑํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
  • id, createdAt, updatedAt ํ•„๋“œ๋Š” ์ž๋™์œผ๋กœ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค.

์™„์„ฑ๋œ urls ํ…Œ์ด๋ธ”์˜ ์Šคํ‚ค๋งˆ๋ฅผ ๋ณด๋ฉด ํ•„์š”ํ•œ ํ•„๋“œ ์ด๋ฆ„๊ณผ ์†์„ฑ์„ ์•Œ ์ˆ˜ ์žˆ๊ณ , ์–ด๋–ป๊ฒŒ ์ ์–ด์•ผ ํ•˜๋Š”์ง€๋Š” ๊ณต์‹ ๋ฌธ์„œ๋ฅผ ์ฐธ๊ณ ํ•˜์˜€๋‹ค.

npx sequelize-cli model:generate --name url --attributes url:string,title:string,visits:integer

migrations์™€ models ํด๋”์—๋„ ๊ฐ ํŒŒ์ผ์ด ์ž˜ ์ƒ์„ฑ๋œ ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

model name

์ด๋•Œ ์ค‘์š”ํ•œ ์ ์€ ๋ชจ๋ธ ๋ช…์„ ๋‹จ์ˆ˜๋กœ ํ‘œ๊ธฐํ•œ๋‹ค. ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ํ›„์—๋Š” ์•Œ์•„์„œ ๋ณต์ˆ˜๋กœ ๋ฐ”๋€Œ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

๋ฐ‘์˜ ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค๊ฐ€ ์žˆ๋Š”๋ฐ

โœ“ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜์„ ํ–ˆ๋‹ค๋ฉด, urls ํ…Œ์ด๋ธ”์ด ์กด์žฌํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค (87ms)

์‹ค์ œ๋กœ ๋ชจ๋ธ๋ช…์„ url๋กœ ์ •ํ•ด์„œ ์ƒ์„ฑํ•ด์ฃผ๋ฉด, ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ํŒŒ์ผ์—์„œ ์ž๋™์œผ๋กœ urls๋กœ ๋ฐ”๋€Œ์–ด ์ž‘์„ฑ๋˜์–ด ์žˆ๋Š” ๊ฑธ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

2. ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜/๋ชจ๋ธ ํŒŒ์ผ์˜ ๊ฐ’ ์„ค์ •

  • ํ•„๋“œ๊ฐ€ ๊ฐ€์ง€๋Š” ํŠน๋ณ„ํ•œ ์š”๊ตฌ์‚ฌํ•ญ(๊ธฐ๋ณธ๊ฐ’ ๋“ฑ)์€ ๋ชจ๋ธ ํŒŒ์ผ์„ ์ง์ ‘ ์ˆ˜์ •ํ•ด์„œ ์ •์˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค์˜ ์กฐ๊ฑด์— url ๋ชจ๋ธ์˜ visits ํ•„๋“œ๋Š” ๊ธฐ๋ณธ๊ฐ’์ด 0์ด์–ด์•ผ ํ•œ๋‹ค. ์–ด๋””์„œ ๊ฐ’์„ ์ •ํ•ด์ค˜์•ผ ํ•˜๋ƒ๋ฉด, ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ํด๋”๊ฐ€ ์•„๋‹ˆ๋ผ ๋ชจ๋ธ์˜ ์‹ค์ œ ๋ฐ์ดํ„ฐ๊ฐ€ ๋‹ด๊ฒจ์žˆ๋Š” ๋ชจ๋ธ ํด๋”์—์„œ ์ž…๋ ฅํ•ด์ค˜์•ผ ํ•œ๋‹ค. ๊ทธ๋ž˜์„œ models์˜ url.js ํŒŒ์ผ์— ๋“ค์–ด๊ฐ€์„œ visits ๊ฐ’์— defaultValue๋ฅผ ์ถ”๊ฐ€ํ•ด์ค€๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์‹ค์ œ๋กœ๋„ ์œ ์–ดํด๋ž˜์Šค์— ์จ์ ธ์žˆ๋‹ค.

๊ณต์‹ ๋ฌธ์„œ๋ฅผ ๋ณด๊ณ  ์ด๋ ‡๊ฒŒ ์ˆ˜์ •ํ–ˆ๋Š”๋ฐ ๋‚˜๋Š” ์ฒ˜์Œ์— ๋‹จ์ˆœํžˆ

url<.init({
	... : ...,
	visits : DataTypes.INTEGER,
  	defaultValue:0
	}, ...)

๋ผ๊ณ  ์ ์—ˆ๋‹ค. ๊ทธ๋žฌ๋”๋‹ˆ ํ†ต๊ณผ๊ฐ€ ๋˜์ง€ ์•Š์•˜๋‹ค.

Q. ์™œ ์†์„ฑ๊ฐ’์„ ๊ฐ์ฒด๋กœ ๋ฌถ์–ด์ค˜์•ผ ํ• ๊นŒ?
A. ๊ฐ์ฒด๋กœ ๋ฌถ์–ด์ฃผ์ง€ ์•Š๊ณ  ๋ฐ–์— ๋นผ๋ฉด ๊ทธ ์นœ๊ตฌ๊ฐ€ visit์„ ์œ„ํ•œ ์นœ๊ตฌ์ธ์ง€ ์–ด๋–ป๊ฒŒ ์•Œ ์ˆ˜ ์žˆ์„๊นŒ? defaultValue๋ผ๋Š” ์ด๋ฆ„์˜ ์ปฌ๋Ÿผ์œผ๋กœ ์ธ์‹ํ•˜์ง€ ์•Š์„๊นŒ?

Q. ์™œ ๋ฐฐ์—ด์ด ์•„๋‹ˆ๊ณ  ๊ตณ์ด ๊ฐ์ฒด์ธ๊ฐ€?
A. []์€ ๋ฌธ์ž์—ด ํ‚ค๋ฅผ ๊ฐ€์งˆ์ˆ˜ ์žˆ๋‚˜?

3. ๋ชจ๋ธ๊ณผ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜์€ ์–ด๋–ป๊ฒŒ ๋‹ค๋ฅผ๊นŒ?

์‹œํ€„๋ผ์ด์ฆˆ๋กœ ๋ชจ๋ธ์„ ์ƒ์„ฑํ•˜๋ฉด ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜์ด ์ƒ๊ธด๋‹ค. ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜์€ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ ์„ค๊ณ„๋„(์Šคํ‚ค๋งˆ ๋””์ž์ธ๊ฐ™์€)๋ผ๊ณ  ์ƒ๊ฐํ•˜๋ฉด ๋œ๋‹ค. ๊ทธ๋Ÿผ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜๋งŒ ํ•„์š”ํ•˜์ง€ ์•Š์„๊นŒ? ์™œ ๋ชจ๋ธ๊นŒ์ง€ ๋งŒ๋“œ๋Š” ๊ฑธ๊นŒ?

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๋ฌธ๋ฒ•์—์„œ DB์—์„œ ์ •๋ณด๋ฅผ ๊ฐ€์ ธ์˜ค๊ฑฐ๋‚˜ ์ถ”๊ฐ€ํ•˜๊ฑฐ๋‚˜ ์‚ญ์ œํ•˜๋Š” ๋กœ์ง์„ ์ž‘์„ฑํ•ด์•ผ ๋˜๋Š”๋ฐ(DB๋ฅผ ์ปจํŠธ๋กคํ•  ์ˆ˜ ์žˆ๋Š” ๋ฌธ๋ฒ•) ๊ทธ๊ฑธ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋ชจ๋ธ์ด ๋งค๊ฐœ์ฒด๊ฐ€ ๋˜๋Š” ๊ฒƒ์ด๋‹ค. ๋”ฐ๋ผ์„œ ๋ชจ๋ธ์€ ๋ฐ์ดํ„ฐ ๋ฒ ์ด์Šค๋ž‘ ๊ด€๋ จ๋œ ๋กœ์ง์„ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์–ธ์–ด๋กœ ์ฒ˜๋ฆฌํ•˜๋Š” ๊ณณ์ด๋ผ๊ณ  ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

4. Running Migration

npx sequelize-cli db:migrate
๋งˆ์ด๊ทธ๋ ˆ์ด์…˜์— ์žˆ๋Š” ํฌ๋ ˆ์ดํŠธ ํ…Œ์ด๋ธ”์„ ์‹คํ–‰ํ•œ๋‹ค. ์ด๊ฑธ ํ•˜๊ธฐ ์ „ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—๋Š” ์•„๋ฌด๊ฒƒ๋„ ์—†๋‹ค. ๋Ÿฌ๋‹ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜์„ ํ•˜๊ฒŒ ๋˜๋ฉด ๋ฐ์ดํ„ฐ ๋ฒ ์ด์Šค์— ํ…Œ์ด๋ธ”์ด ์ƒ์„ฑ๋œ๋‹ค. ์ฆ‰, ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜์„ ์‹คํ–‰์‹œ์ผœ์•ผ ์‹ค์ œ๋กœ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ํ…Œ์ด๋ธ” ๋ฐ์ดํ„ฐ๊ฐ€ ๋“ค์–ด๊ฐ€๋Š” ๊ฒƒ์ด๋‹ค. ์ด๋ฏธ ๋ชจ๋ธ ํŒŒ์ผ์ด ๋งŒ๋“ค์–ด์ ธ์žˆ๋‹ค๋ฉด running migration์„ ํ•ด์„œ ๋ฐ์ดํ„ฐ ๋ฒ ์ด์Šค์™€ ์—ฐ๊ฒฐํ•ด์ค€๋‹ค.

Part 2 - MVC ์ดํ•ด์™€ Controller ์ž‘์„ฑ

๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ ์ค€๋น„๊ฐ€ ์™„๋ฃŒ๋˜์—ˆ์œผ๋‹ˆ, MVC ํŒจํ„ด์„ ์ ์šฉํ•˜์—ฌ Short.ly์˜ ๋ฐฑ์—”๋“œ ๋ถ€๋ถ„์„ ์™„์„ฑํ•ฉ์‹œ๋‹ค. ๋ผ๊ณ  ํ•œ๋‹ค.

  ๐Ÿš€ (2-3) controller ๊ตฌํ˜„
    5) POST /links์€ url์„ ๋ฐ›์•„ ๋‹จ์ถ• url๋กœ ๋งŒ๋“ญ๋‹ˆ๋‹ค
    6) GET /links๋Š” urls ํ…Œ์ด๋ธ”์˜ ๋ชฉ๋ก์„ JSON์˜ ํ˜•ํƒœ๋กœ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค
    7) GET /links/:id ์„ ์š”์ฒญํ•˜๋ฉด url ํ•„๋“œ๊ฐ’์œผ๋กœ ๋ฆฌ๋””๋ ‰์…˜ํ•ฉ๋‹ˆ๋‹ค
    8) GET /links/:id ์„ ์š”์ฒญํ•˜๋ฉด, ํ•ด๋‹น ๋ ˆ์ฝ”๋“œ์˜ visit count๊ฐ€ 1 ์ฆ๊ฐ€ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค

MVC

๋ธŒ๋ผ์šฐ์ €๋Š” ๋ทฐ๋ž‘ ์†Œํ†ต์„ ํ•ด์„œ ํŒŒ์‹ฑํ•œ ํ›„ ์‚ฌ์šฉ์žํ•œํ…Œ ๋ทฐ๋ฅผ ๋ณด์—ฌ์ค€๋‹ค.
์–ด๋–ป๊ฒŒ ๋™์ž‘ํ•˜๋Š” ๊ฑธ๊นŒ?

๋จผ์ €, ๋ธŒ๋ผ์šฐ์ €์— ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ์„œ๋ฒ„์— ์š”์ฒญ์„ ํ•œ๋‹ค. ์ด๋•Œ ๋ผ์šฐํ„ฐ๋ฅผ ๋จผ์ € ๊ฑฐ์นœ๋‹ค. ๊ทธ ํ›„ ๋ผ์šฐํŒ… ๋œ ์š”์ฒญ๋“ค์ด ์ปจํŠธ๋กค๋Ÿฌ๋ฅผ ํ†ตํ•ด์„œ ํ˜๋Ÿฌ๊ฐ„๋‹ค. ์ด ์ปจํŠธ๋กค๋Ÿฌ๋Š” ์ด์ œ ๋ฐ์ดํ„ฐ ๋ฒ ์ด์Šค์™€ ์—ฐ๊ฒฐ์ด ๋˜์–ด์•ผํ•˜๊ธฐ ๋•Œ๋ฌธ์—, ๋ฐ์ดํ„ฐ ๋ฒ ์ด์Šค๋ž‘ ๊ด€๋ จ๋œ ๋กœ์ง์„ ์ฒ˜๋ฆฌํ•˜๋Š” ๊ณณ์ธ ๋ชจ๋ธ(DB์™€ ์†Œํ†ต = sequelize ORM)๊ณผ ์†Œํ†ต์„ ํ•œ๋‹ค.

Controller ์ž‘์„ฑ ๋ฐ Router ์—ฐ๊ฒฐ

  ๐Ÿš€ (2-1) controller ์ž‘์„ฑ
    1) links controller ํŒŒ์ผ์ด ์กด์žฌํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค
    2) links controller์—๋Š” get, post ๋ฉ”์†Œ๋“œ๊ฐ€ ๊ฐ๊ฐ ์กด์žฌํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค
    
================================================================================

  ๐Ÿš€ (2-2) router ์—ฐ๊ฒฐ
    3) "before all" hook for "POST /links๋Š” links controller์˜ post ๋ฉ”์†Œ๋“œ๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค"
    4) "after all" hook for "GET /links๋Š” links controller์˜ get ๋ฉ”์†Œ๋“œ๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค"

ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค ํŒŒ์ผ์„ ๋ณด๊ณ , controllers ํด๋” ์•ˆ์— links ํด๋”๊ฐ€ ์žˆ์–ด์•ผ ํ•˜๊ณ  ๊ทธ ์•ˆ์— index.jsํŒŒ์ผ์„ ์ž‘์„ฑํ•ด์•ผ ๋œ๋‹ค๋Š” ๊ฑธ ํŒŒ์•…ํ–ˆ๋‹ค. ํด๋”์™€ ํŒŒ์ผ ์ƒ์„ฑ ํ›„ get, post ๋ฉ”์†Œ๋“œ๋ฅผ ์ถ”๊ฐ€ํ•ด์คฌ๋‹ค. router๋ฅผ ์—ฐ๊ฒฐํ•ด์ฃผ๊ธฐ ์œ„ํ•ด์„œ exportํ•ด์ค€ ํ›„ links ํด๋”์—์„œ importํ•ด์ฃผ๊ณ  ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค์— ๋งž๊ฒŒ ์—ฐ๊ฒฐํ•ด์ฃผ์—ˆ๋‹ค.

controller ๊ตฌํ˜„

  ๐Ÿš€ (2-3) controller ๊ตฌํ˜„
    5) POST /links์€ url์„ ๋ฐ›์•„ ๋‹จ์ถ• url๋กœ ๋งŒ๋“ญ๋‹ˆ๋‹ค
    6) GET /links๋Š” urls ํ…Œ์ด๋ธ”์˜ ๋ชฉ๋ก์„ JSON์˜ ํ˜•ํƒœ๋กœ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค
    7) GET /links/:id ์„ ์š”์ฒญํ•˜๋ฉด url ํ•„๋“œ๊ฐ’์œผ๋กœ ๋ฆฌ๋””๋ ‰์…˜ํ•ฉ๋‹ˆ๋‹ค
    8) GET /links/:id ์„ ์š”์ฒญํ•˜๋ฉด, ํ•ด๋‹น ๋ ˆ์ฝ”๋“œ์˜ visit count๊ฐ€ 1 ์ฆ๊ฐ€ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค

controller ๋กœ์ง

bitly
๊ธด url์„ ์งง๊ฒŒ ์ถ•์•ฝํ•ด์ฃผ๋Š” ์‚ฌ์ดํŠธ! ๋ฆฌ๋‹ค์ด๋ ‰ํŠธ๋ฅผ ํ†ตํ•ด ์—ฐ๊ฒฐ
1. ์ค„์ด๊ณ  ์‹ถ์€ URL์„ ๋„ฃ๋Š”๋‹ค.
2. Shorten์„ ๋ˆ„๋ฅธ๋‹ค
3. ์ถ•์•ฝ๋œ ๋งํฌ๊ฐ€ ์ƒ์„ฑ๋œ๋‹ค
4. ํ•ด๋‹น ๋งํฌ๋ฅผ ๋ˆ„๋ฅด๋ฉด ์›๋ณธ URL๋กœ ์ด๋™ํ•œ๋‹ค

POST links ์ปจํŠธ๋กค๋Ÿฌ ๋กœ์ง
1. URL์„ ํฌ์ŠคํŠธ ์š”์ฒญ์œผ๋กœ ๋ฐ›๋Š”๋‹ค { url :codestate.com}
2. ์š”์ฒญ์— ์žˆ๋Š” ์ฃผ์†Œ๋ฅผ db์— ๋ ˆ์ฝ”๋“œ๋กœ ์ƒ์„ฑ
3. 2-1) ์ฝ”๋“œ์Šคํ…Œ์ด์ธ  url์ด ์ €์žฅ
4. 2-2) url์— id๊ฐ€ ์ €์žฅ -> get ์š”์ฒญ์— ์“ฐ์ž„
5. 2-3) ํ™ˆํŽ˜์ด์ง€์— ํƒ€์ดํ‹€์ด ์ €์žฅ
6. 2-4) ๋ฐฉ๋ฌธ ํšŸ์ˆ˜๊ฐ€ ์ €์žฅ(visitsํ•„๋“œ)-> ๋ˆ„๊ตฐ๊ฐ€ ๋ฆฌ๋‹ค์ด๋ ‰ํŠธ ํ•  ๋•Œ๋งˆ๋‹ค ์—…๋ฐ์ดํŠธ๊ฐ€ ๋œ๋‹ค
7. ๋งŒ์•ฝ ์ด๋ฏธ ์กด์žฌํ•˜๋Š” url์ด๋ผ๋ฉด ๊ทธ๋ƒฅ ๋„˜์–ด๊ฐ„๋‹ค

GET links/:id ์ปจํŠธ๋กค๋Ÿฌ ๋กœ์ง
1. Links/1 get ์š”์ฒญ์ด ์˜ค๋ฉด ๋ ˆ์ฝ”๋“œ๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๊ฒŒ ์•„๋‹ˆ๋ผ ๋ ˆ์ฝ”๋“œ๋ฅผ ์กฐํšŒํ•œ๋‹ค (id๋ฅผ ๊ฐ€์ง€๊ณ )
2. ํ•ด๋‹น ๋ ˆ์ฝ”๋“œ url์„ ์ปจํŠธ๋กค๋Ÿฌ์—์„œ ๋ฆฌ๋‹ค์ด๋ ‰ํŠธ ์‹œํ‚ด
3. ๊ทธ๋ฆฌ๊ณ  visits ํ•„๋“œ ๊ฐ’์„ 1 ์ถ”๊ฐ€

profile
ํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ์ƒ๊ฐ์ด ์ •๋ง ๋‚˜๋ฅผ ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋งŒ๋“ค์–ด์ค€๋‹ค.
post-custom-banner

0๊ฐœ์˜ ๋Œ“๊ธ€