Unit10 - [Web Server] ๊ธฐ์ดˆ_2

์˜ˆ์ง„ยท2022๋…„ 10์›” 15์ผ
0

๐Ÿ”ฅ Refactor Express

Express : Node.js ํ™˜๊ฒฝ์—์„œ ์›น ์„œ๋ฒ„, API ์„œ๋ฒ„๋ฅผ ์ œ์ž‘ํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ๋˜๋Š” ํ”„๋ ˆ์ž„์›Œํฌ

  • Express๋กœ ๊ตฌํ˜„ํ•œ ์„œ๋ฒ„๊ฐ€ Node.js HTTP๋ž‘ ๋‹ค๋ฅธ ์ 
    - ๋ฏธ๋“ค์›จ์–ด๋ฅผ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๋‹ค.
    - ๋ผ์šฐํ„ฐ๋ฅผ ์ œ๊ณตํ•œ๋‹ค.

1. Express ์‹œ์ž‘ํ•˜๊ธฐ

1) npm install express ๋ช…๋ น์œผ๋กœ express๋ฅผ ์„ค์น˜ํ•œ๋‹ค.

2) ๊ฐ„๋‹จํ•œ ์›น ์„œ๋ฒ„ ๋งŒ๋“ค๊ธฐ

const express = require('express')
const app = express()
// 3000๋ฒˆ ํฌํŠธ ์—ฐ๊ฒฐ
const port = 3000 

app.get('/', (req, res) => {
  res.send('Hi')
})

app.listen(port, () => {
  console.log(`Open port ${port}`)
})

3) ๋ผ์šฐํŒ… : ๋ฉ”์„œ๋“œ์™€ url์— ๋”ฐ๋ผ ๋ถ„๊ธฐ(Routing)ํ•˜๊ธฐ

๋ผ์šฐํŒ…(Routing) : ํŠน์ • ๋ฉ”์„œ๋“œ์™€ url( /lower, /upper ... )๋กœ ๋ถ„๊ธฐ์ ์„ ๋งŒ๋“œ๋Š” ๊ฒƒ

ํด๋ผ์ด์–ธํŠธ๋Š” ํŠน์ •ํ•œ HTTP ์š”์ฒญ ๋ฉ”์„œ๋“œ(GET, POST ...)์™€ ํ•จ๊ป˜ ์„œ๋ฒ„์˜ ํŠน์ • URI(๋˜๋Š” ๊ฒฝ๋กœ)๋กœ HTTP ์š”์ฒญ์„ ๋ณด๋‚ธ๋‹ค. ๋ผ์šฐํŒ…์€ ํด๋ผ๋ฆฌ์–ธํŠธ ์š”์ฒญ์— ํ•ด๋‹นํ•˜๋Š” Endpoint์— ๋”ฐ๋ผ ์„œ๋ฒ„๊ฐ€ ์‘๋‹ตํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๊ฒฐ์ •ํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

const router = express.Router()

router.get('/lower', (req, res) => {
  res.send(data);
})

router.post('/lower', (rea, res) => {
  // ... ์ƒ๋žต
})

=> Express๋Š” ํ”„๋ ˆ์ž„์›Œํฌ ์ž์ฒด์—์„œ ๋ผ์šฐํ„ฐ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•œ๋‹ค.


2. Middleware

๋ฏธ๋“ค์›จ์–ด(Middleware) : ํ”„๋กœ์„ธ์Šค ์ค‘๊ฐ„์— ๊ด€์—ฌํ•˜์—ฌ ํŠน์ • ์—ญํ• ์„ ์ˆ˜ํ–‰ํ•œ๋‹ค.

- ๋ฏธ๋“ค์›จ์–ด์˜ ๊ตฌ์„ฑ

์•„๋ž˜ ๊ทธ๋ฆผ์€ endpoint๊ฐ€ /์ด๋ฉด์„œ, ํด๋ผ์ด์–ธํŠธ๋กœ๋ถ€ํ„ฐ GET ์š”์ฒญ์„ ๋ฐ›์•˜์„ ๋•Œ ์ ์šฉ๋˜๋Š” ๋ฏธ๋“ค์›จ์–ด์ด๋‹ค.

๋ฏธ๋“ค์›จ์–ด ์ž‘์„ฑ์‹œ ํŒŒ๋ผ๋ฏธํ„ฐ ์ˆœ์„œ์— ์œ ์˜ํ•ด์•ผ ํ•œ๋‹ค. (req, res, next)
req : ์š”์ฒญ(request) , res : ์‘๋‹ต(response) , next : ๋‹ค์Œ ๋ฏธ๋“ค์›จ์–ด๋ฅผ ์‹คํ–‰ํ•˜๋Š” ์—ญํ• 


์ž์ฃผ ์‚ฌ์šฉํ•˜๋Š” ๋ฏธ๋“ค์›จ์–ด
1) POST ์š”์ฒญ ๋“ฑ์— ํฌํ•จ๋œ body(payload)๋ฅผ ๊ตฌ์กฐํ™”ํ•  ๋•Œ(์‰ฝ๊ฒŒ ์–ป์–ด๋‚ด๊ณ ์ž ํ•  ๋•Œ)
2) ๋ชจ๋“  ์š”์ฒญ/์‘๋‹ด์— CORS ํ—ค๋”๋ฅผ ๋ถ™์—ฌ์•ผ ํ•  ๋•Œ
3) ๋ชจ๋“  ์š”์ฒญ์— ๋Œ€ํ•ด url์ด๋‚˜ ๋ฉ”์„œ๋“œ๋ฅผ ํ™•์ผํ•  ๋•Œ
4) ์š”์ฒญ ํ—ค๋”์— ์‚ฌ์šฉ์ž ์ธ์ฆ ์ •๋ณด๊ฐ€ ๋‹ด๊ฒจ์žˆ๋Š”์ง€ ํ™•์ธํ•  ๋•Œ

case 1: POST ์š”์ฒญ ๋“ฑ์— ํฌํ•จ๋œ body(payload)๋ฅผ ๊ตฌ์กฐํ™”ํ•  ๋•Œ

Node.js๋กœ HTTP body(payload)๋ฅผ ๋ฐ›์„ ๋•Œ๋Š” Buffer๋ฅผ ์กฐํ•ฉํ•ด์„œ body๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ๋‹ค.
(๋„คํŠธ์›Œํฌ ์ƒ์˜ chunk๋ฅผ ํ•ฉ์น˜๊ณ , buffer๋ฅผ ๋ฌธ์ž์—ด๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ์ž‘์—…์ด ํ•„์š”ํ•˜๋‹ค.)

let body = [];
request.on('data', (chunk) => {
  body.push(chunk);
}).on('end', () => {
  body = Buffer.concat(body).toString();
});

=> body-parser ๋ฏธ๋“ค์›จ์–ด๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์œ„ ๊ณผ์ •์„ ๊ฐ„๋‹จํ•˜๊ฒŒ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค.

const bodyParser = require('body-parser');
const jsonParser = bodyParser.json();

// ... ์ƒ๋žต
app.post('/users', jsonParser, function (req, res) {
  
})

=> Express v4.16.0 ๋ถ€ํ„ฐ๋Š” body-parser๋ฅผ ๋”ฐ๋กœ ์„ค์น˜ x, Express ๋‚ด์žฅ ๋ฏธ๋“ค์›จ์–ด์ธ express.json() ์‚ฌ์šฉ

const jsonParser = express.json({strict: false});

// ... ์ƒ๋žต
app.post('/api/users', jsonParser, function (req, res) {

})
  • express.json([์˜ต์…˜])
    - express.json({strict: false})
    : ๋ฐฐ์—ด๊ณผ ๊ฐ์ฒด๋งŒ ํ—ˆ์šฉํ•˜๋Š” ๊ฒƒ์„ ๋น„ํ™œ์„ฑํ™”(false)ํ•œ๋‹ค. ๋น„ํ™œ์„ฑํ™”๋˜๋ฉด JSON.parse๊ฐ€ ํ—ˆ์šฉํ•˜๋Š” ๋ชจ๋“  ํ•ญ๋ชฉ๋“ค์„ ์ˆ˜์šฉํ•œ๋‹ค.

case 2: ๋ชจ๋“  ์š”์ฒญ/์‘๋‹ต์— CORS ํ—ค๋”๋ฅผ ๋ถ™์ผ ๋•Œ

Node.js HTTP ๋ชจ๋“ˆ์„ ์ด์šฉํ•œ ์ฝ”๋“œ์— CORS ํ—ค๋”๋ฅผ ๋ถ™์ด๋ ค๋ฉด, writeHead ๋ฉ”์„œ๋“œ๋ฅผ ์ด์šฉํ•˜์—ฌ ๋ผ์šฐํŒ…๋งˆ๋‹ค ํ—ค๋”๋ฅผ ๋งค๋ฒˆ ๋„ฃ์–ด์ฃผ์–ด์•ผ ํ•˜๋ฉฐ, OPTIONS ๋ฉ”์„œ๋“œ์— ๋Œ€ํ•œ ๋ผ์šฐํŒ…๋„ ๋”ฐ๋กœ ๊ตฌํ˜„ํ•ด์•ผํ•œ๋‹ค.
๊ทธ๋Ÿฌ๋‚˜ cors ๋ฏธ๋“ค์›จ์–ด๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ด ๊ณผ์ •์„ ๊ฐ„๋‹จํ•˜๊ฒŒ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค.

const cors = require('cors');

// ... ์ƒ๋žต

// ๋ชจ๋“  ์š”์ฒญ์— ๋Œ€ํ•ด CORS ํ—ˆ์šฉ
app.use(cors());

// ํŠน์ • ์š”์ฒญ์— ๋Œ€ํ•ด CORS ํ—ˆ์šฉ
app.get('/products/:id', cors(), function (req, res, next) {
  res.json({msg: 'This is CORS-enabled for a Single Route'})
})

case 3: ๋ชจ๋“  ์š”์ฒญ์— ๋Œ€ํ•ด url์ด๋‚˜ ๋ฉ”์„œ๋“œ๋ฅผ ํ™•์ธํ•  ๋•Œ

๋กœ๊ฑฐ(logger) : ๋””๋ฒ„๊น…์ด๋‚˜, ์„œ๋ฒ„ ๊ด€๋ฆฌ์— ๋„์›€์ด ๋˜๊ธฐ ์œ„ํ•ด console.log๋กœ ์ ์ ˆํ•œ ๋ฐ์ดํ„ฐ๋‚˜ ์ •๋ณด ์ถœ๋ ฅ

const express = require('express');
const app = express();

const myLogger = function (req, res, next) {
  console.log('Logged');
  next();
};

// ํŠน์ • endpoint๊ฐ€ ์•„๋‹Œ, ๋ชจ๋“  ์š”์ฒญ์— ๋™์ผํ•œ ๋ฏธ๋“ค์›จ์–ด ์ ์šฉํ•˜๋ ค๋ฉด app.use ์‚ฌ์šฉ
app.use(myLogger);

app.get('/', function (req, res) {
  res.send('Hi');
});

app.listen(3000);

case 4: ์š”์ฒญ ํ—ค๋”์— ์‚ฌ์šฉ์ž ์ธ์ฆ ์ •๋ณด๊ฐ€ ๋‹ด๊ฒจ์žˆ๋Š”์ง€ ํ™•์ธํ•  ๋•Œ

app.use((req, res, next) => {
  // ํ† ํฐ์ด ์žˆ๋Š”์ง€ ํ™•์ธ, ์—†์œผ๋ฉด ๋ฐ›์•„์ค„ ์ˆ˜ ์—†๋‹ค.
  if(req.headers.token) {
    req.isLoggedIn = true;
    next();
  } else {
    res.status(400).send('invalid user')
  }
})

์œ„ ์ฝ”๋“œ๋Š” HTTP ์š”์ฒญ์—์„œ ํ† ํฐ์„ ํ†ตํ•ด ๋กœ๊ทธ์ธ ์—ฌ๋ถ€๋ฅผ ํ™•์ธํ•˜๋Š” ๋ฏธ๋“ค์›จ์–ด ์˜ˆ์‹œ์ด๋‹ค.

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