/server-study

nodejs, express personal study repository

Primary LanguageJavaScript

server_study

๐Ÿ”† server study repository ๐Ÿ”† - ์„œ๋ฒ„ ๋‰ด๋น„์˜ ๊ธฐ๋ณธ๊ธฐ๋ฅผ ์Œ“๊ธฐ ์œ„ํ•œ ์…€ํ”„ ์Šคํ„ฐ๋””

์ฐธ๊ณ ์ž๋ฃŒ: ์ƒํ™œ์ฝ”๋”ฉ, 26th Server seminar ์ž๋ฃŒ

Javascript

Scope

Function Scope

  • function ๋ธ”๋ก๋งŒ์„ ๋ฒ”์œ„๋กœ ์ธ์ •
  • ์ „์—ญ ํ•จ์ˆ˜ ์™ธ๋ถ€์—์„œ ์ƒ์„ฑํ•œ ๋ณ€์ˆ˜๋Š” ๋ชจ๋‘ ์ „์—ญ ๋ณ€์ˆ˜

Block Scope

  • ๋ธ”๋ก์˜ ๋ฒ”์œ„๋Š” if, while, for, funciton ๋“ฑ์˜ ์ค‘๊ด„ํ˜ธ ์ฝ”๋“œ ๋ธ”๋ก ๋‚ด๋ถ€์—์„œ๋งŒ ์œ ํšจ
  • ์ฝ”๋“œ ๋ธ”๋ก ์™ธ๋ถ€์—์„œ๋Š” ์ฐธ์กฐ ๋ถˆ๊ฐ€๋Šฅ

JSON

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๊ฐ์ฒด ํ‘œํ˜„์‹

  • ์ด๋ฆ„๊ณผ ๊ฐ’์œผ๋กœ ๊ตฌ์„ฑ๋œ ํ”„๋กœํผํ‹ฐ์˜ ์ •๋ ฌ๋˜์ง€ ์•Š์€ ์ง‘ํ•ฉ

  • ํด๋ผ์™€ ํ†ต์‹  ์‹œ ์ฃผ๋กœ ์‚ฌ์šฉ - application/json

var sehwa = {
    name: 'sehwa ryu',
    age : 22,
    part : 'iOS',
    study : ['happy-algorithm', 'wangchobo'],
    printName : function () {
        console.log('name', this.name)
    }, 
    printAge : function () {
        console.log('age', this.age)
    }

}

Node.js

๐ŸŒŸ ๋ณ€์ˆ˜ ์„ ์–ธ ๋ฐฉ๋ฒ•

var: ๋ณ€์ˆ˜, function scope

let: ์ƒ์ˆ˜, block scope

=> ๊ทธ๋ ‡๋‹ค๋ฉด const๋Š”?

let๊ณผ const์˜ ์ฐจ์ด๋Š” ๋ณ€์ˆ˜์˜ immutable ์—ฌ๋ถ€์ด๋‹ค. let์€ ๋ณ€์ˆ˜์— ์žฌํ• ๋‹น์ด ๊ฐ€๋Šฅํ•˜์ง€๋งŒ, const๋Š” ๋ณ€์ˆ˜ ์žฌ์„ ์–ธ, ์žฌํ• ๋‹น ๋ชจ๋‘ ๋ถˆ๊ฐ€๋Šฅํ•˜๋‹ค.

ํ๋ฆ„ ์ œ์–ด

๐ŸŒŸ ๋™๊ธฐ(sync)์™€ ๋น„๋™๊ธฐ(async)์˜ ์ฐจ์ด (์ค‘์š”!!)

์‰ฝ๊ฒŒ ๋งํ•˜๋ฉด ์ƒ๋Œ€๋ฐฉ์˜ ์ผ์ • ์‹ ํ˜ธ์— ์˜ํ•ด์„œ ๋‹ค์Œ ๋™์ž‘์ด ์ผ์–ด๋‚˜๋ฉด ๋™๊ธฐ, ์ƒ๋Œ€๋ฐฉ์˜ ์ƒํƒœ์™€ ์ƒ๊ด€์—†์ด ์ผ๋ฐฉ์ ์œผ๋กœ ๋™์ž‘ํ•˜๋ฉด ๋น„๋™๊ธฐ๋ผ๊ณ  ํ•œ๋‹ค!

์˜ˆ๋ฅผ ๋“ค์–ด siren ์†Œ๋ฆฌ๋ฅผ ๋‚ผ๋•Œ:

play_sound("siren.wav","๋™๊ธฐ") a=b+c; => ์ด๋Ÿฌ๋ฉด ์‚ฌ์ด๋ Œ ์†Œ๋ฆฌ๊ฐ€ ๋‹ค ๋๋‚œํ›„ a=b+c๊ฐ€ ์‹คํ–‰๋˜๊ณ 

play_sound("siren.wav","๋น„๋™๊ธฐ") a=b+c;

=> ์ด๋Ÿฌ๋ฉด a=b+c ์ดํ•˜ ํ”„๋กœ๊ทธ๋žจ์„ ๊ณ„์† ์ˆ˜ํ–‰ํ•˜๋ฉด์„œ siren์†Œ๋ฆฌ๊ฐ€ ๋‚œ๋‹ค.

๐Ÿ”ฅ node.js์—์„œ๋Š” ๋น„๋™๊ธฐ ์–ธ์–ด์ด๋‹ค. ๋”ฐ๋ผ์„œ ์–ด๋–ค ์ž‘์—…์ด ๋จผ์ € ๋๋‚ ์ง€ ๋ชจ๋ฅด๋Š”๋ฐ, ์ˆœ์ฐจ์ ์ธ ์ž‘์—…์„ ์œ„ํ•ด์„œ ์žˆ๋Š” ํ๋ฆ„์ œ์–ด ๋ฐฉ์‹์ด promise์ด๋‹ค!!

๐ŸŒŸPromise: ES6๋ถ€ํ„ฐ ๊ณต์‹์ ์œผ๋กœ ํฌํ•จ๋œ ํ๋ฆ„ ์ œ์–ด ํŒจํ„ด ๋‚ด๋ถ€์  ์˜ˆ์™ธ์ฒ˜๋ฆฌ ๊ตฌ์กฐ

  • pending: ์ž‘์—…์ด ์ƒˆ๋กœ ์ƒ์„ฑ๋œ ์‹œ์ ์˜ ์ƒํƒœ
  • fulfilled: ์ž‘์—…์ด ์„ฑ๊ณต์ ์œผ๋กœ ์™„๋ฃŒ๋œ ์ƒํƒœ
  • rejected: ์ž‘์—…์ด ์‹คํŒจํ•œ ์ƒํƒœ
// ์ž‘์—…์„ฑ๊ณต
new Promise(function(resolve, reject) {
  resolve();
});
// ์ž‘์—…์‹คํŒจ
new Promise(function(resolve, reject) {
  reject();
});

๐ŸŒŸPromise chaining: ์—ฌ๋Ÿฌ๊ฐœ์˜ ํ”„๋กœ๋ฏธ์Šค๋ฅผ ์—ฐ๊ฒฐํ•˜์—ฌ ์‚ฌ์šฉ

const promise = func1('sopt')

// ์ด๋Ÿฐ์‹์œผ๋กœ ์ค‘์ฒฉํ•ด์„œ ๋งŽ์ด ์‚ฌ์šฉํ•œ๋‹ค!
promise
.then((result) => func2(result))
.then((result) => func3(result))
.catch((result) => console.error(result)) // errorhandler1

๐ŸŒŸAsync & Await: ES7๋ถ€ํ„ฐ ์ง€์›ํ•˜๋Š” ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๋น„๋™๊ธฐ ํŒจํ„ด! ์žฅํ™ฉํ•œ Promise์ฝ”๋“œ๋ฅผ ํ•œ ๋ฒˆ ๋” ๊น”๋”ํ•˜๊ฒŒ ์ค„์—ฌ์คŒ! ๊ธฐ์กด์˜ ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ ๋ฐฉ์‹์ธ ์ฝœ๋ฐฑํ•จ์ˆ˜์™€ Promise์˜ ๋‹จ์ ์„ ๋ณด์™„ํ•˜์—ฌ ์ฝ๊ธฐ ์ข‹์€ ์ฝ”๋“œ๋กœ ๋งŒ๋“ค์–ด ์ค€๋‹ค.

  • promise๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ ๋„ ํšจ๊ณผ์ ์œผ๋กœ ์ฝœ๋ฐฑํ—ฌ์„ ํ•ด๊ฒฐํ•จ. Async๋Š” ์•”๋ฌต์ ์œผ๋กœ promise๋ฅผ ๋ฐ˜ํ™˜
  • Await: Promise๋ฅผ ๊ธฐ๋‹ค๋ฆผ ( ์„ฑ๊ณต or ์‹คํŒจ ) async๋กœ ์ •์˜๋œ ๋‚ด๋ถ€์—์„œ๋งŒ ์‚ฌ์šฉ ๊ฐ€๋Šฅ
// ๊ธฐ๋ณธ ๋ฌธ๋ฒ•
async function ํ•จ์ˆ˜๋ช…() {
  await ๋น„๋™๊ธฐ_์ฒ˜๋ฆฌ_๋ฉ”์„œ๋“œ_๋ช…();
}

Module

node.js ๋‚ด์žฅ๋ชจ๋“ˆ

๐ŸŒŸcrypto: ๋ฌธ์ž์—ด์„ ์•”ํ˜ธํ™”, ๋ณตํ˜ธํ™”, ํ•ด์‹ฑํ•˜๋Š” ๋ชจ๋“ˆ

  • ๋ณตํ˜ธํ™”ํ•  ์ˆ˜ ์—†๋Š” ์•”ํ˜ธํ™” ๋ฐฉ์‹
  • ๋น„๋ฐ€๋ฒˆํ˜ธ ์•”ํ˜ธํ™”์— ์ฃผ๋กœ ์‚ฌ์šฉ
  • ์ฃผ๋กœ ํ•ด์‹œ๊ธฐ๋ฒ•์„ ์‚ฌ์šฉ
/* 
crypto.createHash(algorithm<string>) : ์•”ํ˜ธํ™” ์•Œ๊ณ ๋ฆฌ์ฆ˜. <Hash> ๊ฐ’์„ ๋ฐ˜ํ™˜, ์ฃผ๋กœ sha512๋ฅผ ์‚ฌ์šฉ
hash.update(data<string>) : ๋ณ€ํ™˜ํ•  ๋ฌธ์ž์—ด์„ ๋„ฃ์–ด์คŒ
hash.digest(encoding) : ์ธ์ฝ”๋”ฉํ•  ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ๋„ฃ์–ด์คŒ (base64, hex, latin1), ๊ณ ์ •๋œ ๊ธธ์ด ๊ฐ’์„ ์„ค์ •, ๋ณ€ํ™˜๋œ ๋ฌธ์ž์—ด์„ ๋ฐ˜ํ™˜
*/
const hash = crypto.createHmac('sha256', secret)
                    .update('I love cupcakes')
                    .digest('hex');

๋น„๋ฐ€๋ฒˆํ˜ธ ์ €์žฅ ๋ฐฉ๋ฒ•

  1. ๋‹จ์ˆœ ํ…์ŠคํŠธ -> ๋น„์ถ”
  2. Hashing
  3. Hashing with salt: ํŒจ์Šค์›Œ๋“œ์— ์†Œ๊ธˆ์„ ์ณ์„œ ์•”ํ˜ธํ™”
  4. Key stretching: ํŒจ์Šค์›Œ๋“œ์— ์†Œ๊ธˆ์„ ์ณ์„œ ์•”ํ˜ธํ™” ๊ณผ์ •์„ N๋ฒˆ ์‹คํ–‰
crypto.pbkdf2(password, salt, iterations, keylen, digest, callback)
// pbkdf2 (๋น„๋ฐ€๋ฒˆํ˜ธ, ์†”ํŠธ ๊ฐ’, ๋ฐ˜๋ณต ํšŸ์ˆ˜, ์ถœ๋ ฅ byte, ํ•ด์‹œ ์•Œ๊ณ ๋ฆฌ์ฆ˜, callback)

๐ŸŒŸFile system module: ํŒŒ์ผ ์‹œ์Šคํ…œ์— ์ ‘๊ทผํ•˜๋Š” ๋ชจ๋“ˆ

  • ํŒŒ์ผ ์ƒ์„ฑ, ์‚ญ์ œ, ์ฝ๊ธฐ, ์“ฐ๊ธฐ ๋“ฑ ์ˆ˜ํ–‰ OR ํด๋” ์ƒ์„ฑ, ์‚ญ์ œ

Express

๐ŸŒŸExpress: Node๋ฅผ ์œ„ํ•œ ๋น ๋ฅด๊ณ  ๊ฐ„๊ฒฐํ•œ ์›น ํ”„๋ ˆ์ž„์›Œํฌ

  • HTTP ์š”์ฒญ์— ๋Œ€ํ•ด ๋ผ์šฐํŒ… ๋ฐ ๋ฏธ๋“ค์›จ์–ด ๊ธฐ๋Šฅ ์ œ๊ณต

๐ŸŒŸExpress ๊ตฌ์กฐ

  • bin/www
    • ์„œ๋ฒ„๋ฅผ ์‹คํ–‰ํ•˜๋Š” ์Šคํฌ๋ฆฝํŠธ: ํ”„๋กœ์ ํŠธ์— ํ• ๋‹น๋˜๋Š” ํฌํŠธ ๋ฒˆํ˜ธ๋ฅผ ๋ฐ”๊ฟ€ ์ˆ˜ ์žˆ์Œ
  • public/
    • ๊ฐ์ข… ๋ฆฌ์†Œ์Šค๋“ค ํฌํ•จ: ์ด๋ฏธ์ง€, css, js etc.
  • routes/
    • ํŽ˜์ด์ง€ ๋ผ์šฐํŒ…๊ณผ ๊ด€๋ จ๋œ ํŒŒ์ผ ์ €์žฅ: ์ฃผ์†Œ๋ณ„๋กœ ๋ผ์šฐํ„ฐ๋“ค์„ ๋ชจ์•„๋‘ 
    • URL๋ณ„๋กœ ์‹คํ–‰๋˜๋Š” ์‹ค์ œ ์„œ๋ฒ„ ๋กœ์ง
    • index.js์„ ์‹œ์ž‘์œผ๋กœ ๊ด€๋ฆฌํ•ด์ฃผ๋ฉด ๋จ!
  • views/
    • Jade, ejs ๋“ฑ ํ…œํ”Œ๋ฆฟ ํŒŒ์ผ์„ ๋ชจ์•„๋‘ 
    • ์›น ์„œ๋ฒ„ ์‚ฌ์šฉ ์‹œ ํ•ด๋‹น ํด๋”์˜ ํŒŒ์ผ๋“ค์„ ์‚ฌ์šฉํ•ด์„œ ๋ Œ๋”๋ง
  • /app.js
    • ํ”„๋กœ์ ํŠธ์˜ ์ค‘์‹ฌ
    • ํ•ต์‹ฌ์ ์ธ ์„œ๋ฒ„ ์—ญํ• 
    • ๋ฏธ๋“ค์›จ์–ด ๊ด€๋ฆฌ๊ฐ€ ์ด๋ฃจ์–ด์ง
    • ๋ผ์šฐํŒ…์˜ ์‹œ์ž‘์ 
  • /package.json
    • npm ์˜์กด์„ฑ ํŒŒ์ผ๋“ค
    • ํ˜„์žฌ ํ”„๋กœ์ ํŠธ์— ์‚ฌ์šฉ๋œ ๋ชจ๋“ˆ์„ ์„ค์น˜ํ•˜๋Š”๋ฐ ํ•„์š”ํ•œ ๋‚ด์šฉ์„ ๋‹ด์Œ

๐ŸŒŸ routing์ด๋ž€?

  • URI(๋˜๋Š” ๊ฒฝ๋กœ) ๋ฐ ํŠน์ •ํ•œ HTTP ์š”์ฒญ ๋ฉ”์†Œ๋“œ (GET, POST ๋“ฑ) ์ธ ํŠน์ • ์—”๋“œํฌ์ธํŠธ์— ๋Œ€ํ•œ ํด๋ผ์ด์–ธํŠธ ์š”์ฒญ์— ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์‘๋‹ตํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๊ฒฐ์ •
  • Express์—์„œ๋Š” app.js์—์„œ ๋ชจ๋“  ์š”์ฒญ ๊ฒฝ๋กœ๋ฅผ ์ฒ˜๋ฆฌํ•˜์ง€ ์•Š๊ณ , routes ํด๋” ์•„๋ž˜์˜ index.js๋ฅผ ๊ธฐ์ค€์œผ๋กœ ํŒŒ์ผ๋“ค์„ ์ถ”๊ฐ€ํ•˜๋ฉฐ ์ •๋ฆฌ
  • ํ•œ ํŒŒ์ผ์— ๋ชจ๋“  ๋ผ์šฐํŒ…์„ ๊ด€๋ฆฌํ•˜๋Š” ๊ฑด ์ง€์–‘

Express project ์‹คํ–‰์‹œํ‚ค๊ธฐ!

  1. ์ตœ์ƒ์œ„ ํด๋”์—์„œ sudo npm install โ€“g express-generator
  2. express "project"
  3. ./project ์—์„œ npm install
  4. ./project ์—์„œ npm start

๐Ÿ”ฅ ์ฝ”๋“œ๋ฅผ ์ˆ˜์ •ํ–ˆ์„ ๋•Œ๋Š” ์‹คํ–‰๋ผ์žˆ๋Š” ์„œ๋ฒ„๋ฅผ ์ค‘๋‹จํ•˜๊ณ  (command+c) npm start๋ฅผ ๋‹ค์‹œ ํ•ด์ฃผ์–ด์•ผ ํ•œ๋‹ค!

HTTP

๐ŸŒŸ HTTP Status code : ์•Œ์•„๋‘๊ธฐ!

Code Status
200 Success
201 Created new resource from the server
204 Success - no content to return
304 Cache purpose - no modification
400 Bad request - server did not interpret request
401 Unauthorized
404 Not found - cannot find the resource/page
500 Internal Server error

๐ŸŒŸ Request (Client -> Server)

  1. URL
  2. Header (token ๋“ฑ์˜ ๋ถ€๊ฐ€์ ์ธ ์ •๋ณด)
  3. Body (XML, JSON ๋“ฑ์˜ ๋ฐ์ดํ„ฐ)

๐ŸŒŸ Response (Server -> Client)

  1. Body (XML, JSON ๋“ฑ์˜ ๋ฐ์ดํ„ฐ)

CRUD

๐ŸŒŸCRUD๋ž€? : ๋Œ€๋ถ€๋ถ„์˜ ์ปดํ“จํ„ฐ ์†Œํ”„ํŠธ์›จ์–ด๊ฐ€ ๊ฐ€์ง€๋Š” ๊ธฐ๋ณธ์ ์ธ ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ ๊ธฐ๋Šฅ

CRUD ACTION HTTP Method SQL
CREATE ์ƒ์„ฑ POST INSERT
READ ์กฐํšŒ GET SELECT
UPDATE ์ˆ˜์ • PUT UPDATE
DELETE ์‚ญ์ œ DELETE DELETE

Database

๐ŸŒŸ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ •๊ทœํ™”๋ž€? : RDB ์„ค๊ณ„๋ฅผ ์ง๊ด€์ ์ด๊ณ  ๋…ผ๋ฆฌ์ ์œผ๋กœ ๋งŒ๋“œ๋Š” ๊ณผ์ •

  • ๋ถˆํ•„์š”ํ•œ ๋ฐ์ดํ„ฐ ์ œ๊ฑฐ
  • ๋ฐ์ดํ„ฐ์˜ ์ค‘๋ณต ์ตœ์†Œํ™” ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ค๋ฃจ๋ฉด์„œ ์ƒ๊ธฐ๋Š” ์ด์ƒํ˜„์ƒ ๋ฐฉ์ง€
  • ๊ฐœ๋ฐœ ์ค‘ ๋ฐ์ดํ„ฐ์˜ ๋ณ€ํ™”๊ฐ€ ์ƒ๊ฒจ๋„ ์„ค๊ณ„๋ฅผ ์žฌ๊ตฌ์„ฑํ•  ํ•„์š”์„ฑ ๊ฐ์†Œ

์ •๊ทœํ™”์˜ ์ด์ƒํ˜„์ƒ

  • ์‚ฝ์ž…์ด์ƒ : ์ƒˆ ๋ฐ์ดํ„ฐ๋ฅผ ์‚ฝ์ž…ํ•˜๊ธฐ ์œ„ํ•ด ๋ถˆํ•„์š”ํ•œ ๋ฐ์ดํ„ฐ๋„ ํ•จ๊ป˜ ์‚ฝ์ž…ํ•ด์•ผ ํ•˜๋Š” ๋ฌธ์ œ
  • ๊ฐฑ์‹ ์ด์ƒ : ์ค‘๋ณต ํŠœํ”Œ ์ค‘ ์ผ๋ถ€๋งŒ ๋ณ€๊ฒฝํ•˜์—ฌ ๋ฐ์ดํ„ฐ๊ฐ€ ๋ถˆ์ผ์น˜ํ•˜๊ฒŒ ๋˜๋Š” ๋ชจ์ˆœ์˜ ๋ฌธ์ œ
  • ์‚ญ์ œ์ด์ƒ : ํŠœํ”Œ์„ ์‚ญ์ œํ•˜๋ฉด ๊ผญ ํ•„์š”ํ•œ ๋ฐ์ดํ„ฐ๊นŒ์ง€ ํ•จ๊ป˜ ์‚ญ์ œ๋˜๋Š” ๋ฐ์ดํ„ฐ ์†์‹ค์˜ ๋ฌธ์ œ

1์ฐจ ์ •๊ทœํ™”: Row ๋งˆ๋‹ค ์นผ๋Ÿผ์˜ ๊ฐ’์ด 1๊ฐœ์”ฉ๋งŒ ์žˆ์–ด์•ผ ํ•จ

2์ฐจ ์ •๊ทœํ™”: ๋ถ€๋ถ„ ํ•จ์ˆ˜์  ์ข…์†์„ ์ œ๊ฑฐ

  • X์˜ ๊ฐ’์„ ์•Œ๋ฉด Y์˜ ๊ฐ’์„ ๋ฐ”๋กœ ์‹๋ณ„ํ•  ์ˆ˜ ์žˆ๊ณ , X์˜ ๊ฐ’์— Y์˜ ๊ฐ’์ด ๋‹ฌ๋ผ์งˆ ๋•Œ, Y๋Š” X์— ํ•จ์ˆ˜์  ์ข…์†์ด๋ผ๊ณ  ํ•จ

3์ฐจ ์ •๊ทœํ™”: ์ดํ–‰์  ํ•จ์ˆ˜ ์ข…์†์„ ์ œ๊ฑฐ

BCNF: ๊ฒฐ์ •์ž๊ฐ€ ํ›„๋ณด ํ‚ค๊ฐ€ ์•„๋‹ˆ๋ฉด ์ œ๊ฑฐ

  • ๋ชจ๋“  ๊ฒฐ์ •์ž๊ฐ€ ํ›„๋ณดํ‚ค๊ฐ€ ๋˜๋„๋ก ๋งŒ๋“ฆ
    • ํ›„๋ณดํ‚ค: ๋ฆด๋ ˆ์ด์…˜์„ ๊ตฌ์„ฑํ•˜๋Š” ์†์„ฑ๋“ค ์ค‘์—์„œ ํŠœํ”Œ์„ ์œ ์ผํ•˜๊ฒŒ ์‹๋ณ„ํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ•˜๋Š” ์†์„ฑ๋“ค์˜ ๋ถ€๋ถ„์ง‘ํ•ฉ, ์ฆ‰ ๊ธฐ๋ณธํ‚ค๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์†์„ฑ๋“ค์„ ๋งํ•œ๋‹ค.

Transaction

๐ŸŒŸ Transaction์ด๋ž€? : ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ ์ƒํƒœ๋ฅผ ๋ณ€ํ™”์‹œํ‚ค๊ธฐ ์œ„ํ•ด ์ˆ˜ํ–‰ํ•˜๋Š” ์ž‘์—…์˜ ๋‹จ์œ„ -> ์—ฌ๋Ÿฌ ๋‹จ๊ณ„์˜ ์ฒ˜๋ฆฌ๋ฅผ ํ•˜๋‚˜์ฒ˜๋Ÿผ ๋‹ค๋ฃธ

  • commit: transaction์˜ ์‹คํ–‰ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ๋ฐ˜์˜ํ•˜๋Š” ๊ฒƒ
  • Roll-back: transaction์˜ ์‹คํ–‰ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜์˜ํ•˜์ง€ ์•Š๊ณ  ์›์ƒํƒœ๋กœ ๋˜๋Œ๋ฆฌ๋Š” ๊ฒƒ
// transaction ์ ์šฉ ์‹œ์ž‘
connection.beginTransaction(config)

// transaction ๋‚ด ๋ชจ๋“  ์ฟผ๋ฆฌ ์™„๋ฃŒ ํ›„ ๊ฒฐ๊ณผ ๋ฐ˜์˜
connection.commit()

// transaction ๋‚ด ๋ชจ๋“  ์ฟผ๋ฆฌ๊ฐ€ ์ •์ƒ์ ์œผ๋กœ ๋งˆ์น˜์ง€ ๋ชปํ–ˆ๋‹ค๋ฉด ์›์ƒํƒœ๋กœ ๋Œ๋ ค๋†“์Œ
connection.rollBack()

Sequelize

๐ŸŒŸ Sequelize๋ž€?: nodejs์—์„œ mysql์„ ์‰ฝ๊ฒŒ ๋‹ค๋ฃฐ ์ˆ˜ ์žˆ๋„๋ก ๋„์™€์ฃผ๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ

  • sequelize๋Š” ORM(Object-Relational Mapping)๋กœ ๋ถ„๋ฅ˜๊ฐ€ ๋œ๋‹ค. ORM ์€ ๊ฐ„๋‹จํ•˜๊ฒŒ ๊ฐ์ฒด์™€ ๊ด€๊ณ„ํ˜• ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ ๊ด€๊ณ„๋ฅผ ๋งคํ•‘ ํ•ด์ฃผ๋Š” ๋„๊ตฌ์ด๋‹ค. sequelize๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์ฝ”๋“œ๋กœ mysql์„ ์ œ์–ดํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.
  1. sequelize init์„ ํ†ตํ•ด ํ˜ธ์ถœ์„ ํ•˜๋ฉด config, models, migrations, seeders ํด๋”๊ฐ€ ์ƒ๊ธฐ๋Š”๋ฐ models์•ˆ์— index.js๋ฅผ ์ˆ˜์ •ํ•ด์•ผ ํ•œ๋‹ค!
> sequelize init
/* sequelize\models\index.js */
const path = require('path');
const Sequelize = require('sequelize');
const env = process.env.NODE_ENV || 'development';
const config = require(
  path.join(__dirname + '..', 'config', 'config.json')
)[env];
const db = {};
const sequelize = new Sequelize(
  config.database, config.username, config.password, config
);
db.sequelize = sequelize;
db.Sequelize = Sequelize;
module.exports = db;

๐ŸŒŸ Sequelize Migration: ์šด์˜์ค‘์ธ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ๋ณ€๊ฒฝํ•˜๋Š” ์ž‘์—…!

  • ์ž‘์—…์„ ํ•˜๋‹ค๋ณด๋ฉด ์‚ฌ์šฉ์ค‘์ธ ๋””๋น„์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ˆ˜์ •ํ•ด์•ผํ•  ์ผ์ด ์ƒ๊ธด๋‹ค. ๊ทธ๋Ÿด๋•Œ๋Š” ์ด ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค!
  1. config.json ํŒŒ์ผ์—์„œ database ์ •๋ณด ์ˆ˜์ •ํ•˜๊ธฐ

  2. ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›์•„์˜ค๋Š” ๊ตฌ์กฐ์ฒด ํŒŒ์ผ.js์—์„œ ์ •๋ณด ์ˆ˜์ •ํ•˜๊ธฐ

  3. ์ตœ์ƒ์œ„ ํด๋”์—์„œ $ sequelize migration:create --name 'name'

  4. ์œ„์˜ ๋ช…๋ น์–ด๋ฅผ ์‹คํ–‰ํ•˜๋ฉด migrations ํด๋”์— ํƒ€์ž„์Šคํƒฌํ”„๊ฐ€ ์ฐํžŒ ํŒŒ์ผ์ด ํ•˜๋‚˜ ์ƒ์„ฑ๋œ๋‹ค. eg. 20160113211643-unnamed-migration.js

  5. ์ด ํŒŒ์ผ์€ ํ•ด๋‹น ์ฝ”๋“œ ํ…œํ”Œ๋ฆฟ์œผ๋กœ ๊ตฌ์„ฑ๋˜์–ด ์žˆ๋‹ค. ์ด ๋ชจ๋“ˆ์€ up()๊ณผ down() ๋ฉ”์†Œ๋“œ๋ฅผ ๋…ธ์ถœํ•˜๋Š”๋ฐ ๊ฐ ๊ฐ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜๊ณผ ๋กค๋ฐฑ์„ ๋‹ด๋‹นํ•œ๋‹ค. up() ํ•จ์ˆ˜์— ์ƒˆ๋กœ์šด ์ปฌ๋Ÿผ์„ ์ถ”๊ฐ€ํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋ฉด, down() ํ•จ์ˆ˜์—๋Š” ์ถ”๊ฐ€ํ•œ ์ปฌ๋Ÿผ์„ ์‚ญ์ œํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋Š” ์‹์ด๋‹ค!

    "use strict"
    
    module.exports = {
      up: function (queryInterface, Sequelize) {
        /*
          Add altering commands here.
          Return a promise to correctly handle asynchronicity.
    
          Example:
          return queryInterface.createTable('users', { id: Sequelize.INTEGER });
        */
      },
    
      down: function (queryInterface, Sequelize) {
        /*
          Add reverting commands here.
          Return a promise to correctly handle asynchronicity.
    
          Example:
          return queryInterface.dropTable('users');
        */
      },
    }