Jieunny์˜ ๋ธ”๋กœ๊ทธ

S2) Unit 10. [Web Server] Refactor Express ๋ณธ๋ฌธ

CodeStates/learning contents

S2) Unit 10. [Web Server] Refactor Express

Jieunny 2023. 2. 7. 11:58

๐Ÿ“ฃ  Express

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

โœ”๏ธ Node.js HTTP ๋ชจ๋“ˆ๋กœ ์ž‘์„ฑํ•œ ์„œ๋ฒ„์™€ ๋‹ค๋ฅธ ์ 

     โžฐ ๋ฏธ๋“ค์›จ์–ด๋ฅผ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๋‹ค.

     โžฐ ๋ผ์šฐํ„ฐ๋ฅผ ์ œ๊ณตํ•œ๋‹ค.

 

1๏ธโƒฃ Express ์„ค์น˜

npm install express

 

2๏ธโƒฃ ๊ฐ„๋‹จํ•œ ์›น ์„œ๋ฒ„ ๋งŒ๋“ค๊ธฐ

const express = require('express')
const app = express()
const port = 3000

app.get('/', (req, res) => {
	res.send('Hello World!')
})

app.listen(port, () => {
	console.log(`Example app listening on port ${port}`)
})

โžฐ ์‘๋‹ต์œผ๋กœ Hello World!๋ฅผ ๋ณด๋‚ด๋Š” Express ์„œ๋ฒ„ 

 

3๏ธโƒฃ ๋ผ์šฐํŒ…: ํŠน์ • ๋ฉ”์„œ๋“œ์™€ URI๋กœ ๋ถ„๊ธฐ์ ์„ ๋งŒ๋“œ๋Š” ๊ฒƒ

โžฐ ํด๋ผ์ด์–ธํŠธ๋Š” ํŠน์ •ํ•œ HTTP ์š”์ฒญ ๋ฉ”์„œ๋“œ(GET, POST ๋“ฑ)๊ณผ ํ•จ๊ป˜ ์„œ๋ฒ„์˜ ํŠน์ • URI๋กœ HTTP ์š”์ฒญ์„ ๋ณด๋‚ธ๋‹ค.

โžฐ ํด๋ผ์ด์–ธํŠธ์˜ ์š”์ฒญ์— ํ•ด๋‹นํ•˜๋Š” Endpoint์— ๋”ฐ๋ผ ์„œ๋ฒ„๊ฐ€ ์‘๋‹ตํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๊ฒฐ์ •ํ•˜๋Š” ๊ฒƒ

//Node.js
const requestHandler = (req, res) => {
  if(req.url === '/lower') {
    if (req.method === 'GET') {
      res.end(data)
    } else if (req.method === 'POST') {
      req.on('data', (req, res) => {
        // do something ...
      })
    }
  }
}

//Express : ์ž์ฒด์ ์œผ๋กœ ๋ผ์šฐํ„ฐ ๊ธฐ๋Šฅ ์ œ๊ณต
const router = express.Router()

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

router.post('/lower', (req, res) => {
  // do something
})

 

๐Ÿ“ฃ  ๋ฏธ๋“ค์›จ์–ด

โœ”๏ธ express์˜ ๊ฐ€์žฅ ํฐ ์žฅ์ ์œผ๋กœ, ์š”์ฒญ์— ํ•„์š”ํ•œ ๊ธฐ๋Šฅ์„ ๋”ํ•˜๊ฑฐ๋‚˜, ๋ฌธ์ œ๊ฐ€ ๋ฐœ๊ฒฌ๋œ ๊ฒƒ์„ ๋ฐ–์œผ๋กœ ๊ฑท์–ด๋‚ด๋Š” ์—ญํ• 

โžฐ POST ์š”์ฒญ ๋“ฑ์— ํฌํ•จ๋œ body(payload)๋ฅผ ๊ตฌ์กฐํ™”ํ•  ๋•Œ(์‰ฝ๊ฒŒ ์–ป์–ด๋‚ด๊ณ ์ž ํ•  ๋•Œ)

โžฐ ๋ชจ๋“  ์š”์ฒญ/์‘๋‹ต์— CORS ํ—ค๋”๋ฅผ ๋ถ™์—ฌ์•ผ ํ•  ๋•Œ

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

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

 

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

โžฐ Node.js๋กœ HTTP ์š”์ฒญ body๋ฅผ ๋ฐ›๋Š” ์ฝ”๋“œ

let body = [];
request.on('data', (chunk) => {
  body.push(chunk);
}).on('end', () => {
  body = Buffer.concat(body).toString();
  // body ๋ณ€์ˆ˜์—๋Š” ๋ฌธ์ž์—ด ํ˜•ํƒœ๋กœ payload๊ฐ€ ๋‹ด๊ฒจ์ ธ ์žˆ์Šต๋‹ˆ๋‹ค.
});

 

โžฐ body-parser ๋ฏธ๋“ค์›จ์–ด ์‚ฌ์šฉ

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

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

})

 

โžฐ Express ๋‚ด์žฅ ๋ฏธ๋“ค์›จ์–ด express.json() ์‚ฌ์šฉ

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

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

})

โžฐ strict:false ์ฒ˜๋ฆฌ๋ฅผ ํ•ด์ค˜์•ผ Object ํ˜•ํƒœ๊ฐ€ ์•„๋‹Œ ๋ฐ์ดํ„ฐ๋„ ๋ฐ›์„ ์ˆ˜ ์žˆ๋‹ค.

 

2๏ธโƒฃ ๋ชจ๋“  ์š”์ฒญ/์‘๋‹ต์— CORS ํ—ค๋”๋ฅผ ๋ถ™์ผ ๋•Œ

โžฐ Node.js์— CORS๋ฅผ ์ ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•

const defaultCorsHeader = {
  'Access-Control-Allow-Origin': '*',
  'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',
  'Access-Control-Allow-Headers': 'Content-Type, Accept',
  'Access-Control-Max-Age': 10
};

// ์ƒ๋žต
if (req.method === 'OPTIONS') {
  res.writeHead(201, defaultCorsHeader);
  res.end()
}

 

โžฐ cors ๋ฏธ๋“ค์›จ์–ด ์‚ฌ์šฉ

npm install cors
// ๋ชจ๋“  ์š”์ฒญ์— ๋Œ€ํ•ด CORS ํ—ˆ์šฉ
const cors = require('cors');

// ์ƒ๋žต
app.use(cors());
// ํŠน์ • ์š”์ฒญ์— ๋Œ€ํ•ด CORS ํ—ˆ์šฉ
const cors = require('cors')

// ์ƒ๋žต
app.get('/products/:id', cors(), function (req, res, next) {
  res.json({msg: 'This is CORS-enabled for a Single Route'})
})

 

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

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

โžฐ ๊ฐ€์žฅ ๋‹จ์ˆœํ•œ ๋ฏธ๋“ค์›จ์–ด์ธ ๋กœ๊ฑฐ(logger)๋Š” ๋””๋ฒ„๊น…์ด๋‚˜, ์„œ๋ฒ„ ๊ด€๋ฆฌ์— ๋„์›€์ด ๋˜๊ธฐ ์œ„ํ•ด console.log ๋กœ ์ ์ ˆํ•œ ๋ฐ์ดํ„ฐ๋‚˜ ์ •๋ณด๋ฅผ ์ถœ๋ ฅํ•œ๋‹ค.

โžฐ ๋ฏธ๋“ค์›จ์–ด ์‚ฌ์ด์‚ฌ์ด์— ๋กœ๊ฑฐ๋ฅผ ์‚ฝ์ž…ํ•˜์—ฌ ํ˜„์žฌ ๋ฐ์ดํ„ฐ๋ฅผ ํ™•์ธํ•˜๊ฑฐ๋‚˜, ๋””๋ฒ„๊น…์— ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

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

โžฐ req, res๋Š” ์š”์ฒญ, ์‘๋‹ต์ด๊ณ  next๋Š” ๋ฏธ๋“ค์›จ์–ด๋ฅผ ์‹คํ–‰ํ•˜๋Š” ์—ญํ• ์ด๋‹ค.

โžฐ ๋ชจ๋“  ์š”์ฒญ์— ๋™์ผํ•œ ๋ฏธ๋“ค์›จ์–ด๋ฅผ ์ ์šฉํ•˜๋ ค๋ฉด app.use ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค.

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

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

app.use(myLogger);
// ๋ชจ๋“  ์š”์ฒญ์— ๋™์ผํ•œ ๋ฏธ๋“ค์›จ์–ด๋ฅผ ์ ์šฉํ•œ๋‹ค.
// ๋ชจ๋“  ์š”์ฒญ์— ๋Œ€ํ•ด LOGGED๊ฐ€ ์ถœ๋ ฅ๋œ๋‹ค.

app.get('/', function (req, res) {
  res.send('Hello World!');
});

app.listen(3000);

 

โœ๏ธ ๋ชจ๋“  ์š”์ฒญ์— ๋Œ€ํ•ด ๋ฉ”์„œ๋“œ์™€ url ์ถœ๋ ฅํ•˜๊ธฐ

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

const myLogger = function (req, res, next) {
  //req๋ฅผ ํ™œ์šฉํ•ฉ๋‹ˆ๋‹ค.
  console.log(`http request method is ${req.method}, url is ${req.url}`);
  next();
};

app.use(myLogger);

app.get('/', function (req, res) {
  res.send('Hello World!');
});

app.listen(3000);

 

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

โžฐ HTTP ์š”์ฒญ์—์„œ ํ† ํฐ์ด ์žˆ๋Š”์ง€ ํŒ๋‹จํ•˜์—ฌ, ์ด๋ฏธ ๋กœ๊ทธ์ธํ•œ ์‚ฌ์šฉ์ž์ผ ๊ฒฝ์šฐ ์„ฑ๊ณต ์•„๋‹ ๊ฒฝ์šฐ ์—๋Ÿฌ๋ฅผ ๋ณด๋‚ด๋Š” ๋ฏธ๋“ค์›จ์–ด

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

โž• ํ† ํฐ(Token)

๋”๋ณด๊ธฐ

โžฐ ์ฃผ๋กœ ์‚ฌ์šฉ์ž ์ธ์ฆ์— ์‚ฌ์šฉํ•œ๋‹ค.