ABOUT ME

Today
Yesterday
Total
  • Refactor Express
    codeStates front-end/node(server) 2023. 2. 8. 20:13
    ๋ฐ˜์‘ํ˜•

     

     

    ๐Ÿ“Œ Refactor Express

     

     

    ๐Ÿ“Express

     

    Express ์„ค์น˜

     

    npm install express

     

    Hello world! ์˜ˆ์ œ ๋งŒ๋“ค๊ธฐ

     

     

    Express "Hello World" ์˜ˆ์ œ

    Hello world ์˜ˆ์ œ ๊ธฐ๋ณธ์ ์œผ๋กœ ์ด ์•ฑ์€ ์—ฌ๋Ÿฌ๋ถ„์ด ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๋Š” ๊ฐ€์žฅ ๊ฐ„๋‹จํ•œ Express ์•ฑ์ผ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด ์•ฑ์€ ํ•˜๋‚˜์˜ ํŒŒ์ผ๋กœ ๋œ ์•ฑ์ด๋ฉฐ Express ์ƒ์„ฑ๊ธฐ๋ฅผ ํ†ตํ•ด ์–ป๊ฒŒ ๋˜๋Š” ์•ฑ๊ณผ๋Š” ๊ฐ™์ง€ ์•Š์Šต๋‹ˆ๋‹ค. (์ด ์˜ˆ์ œ

    expressjs.com

     

    ๊ณต์‹๋ฌธ์„œ๋ฅผ ํ†ตํ•ด ์‹คํ–‰

     

    1. myapp ๋””๋ ‰ํ† ๋ฆฌ ์ƒ์„ฑ
    2. npm init ์‹คํ–‰
    3. app.js ๋ผ๋Š” ์ด๋ฆ„์˜ ํŒŒ์ผ์„ ์ž‘์„ฑ ํ›„
    4. ๋‹ค์Œ ์ฝ”๋“œ ์ž‘์„ฑ
    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}`)
    })

     

     

    ๐Ÿ’ก Express๋ž€?

    ๐Ÿ“– Express๋Š” ์›น ๋ฐ ๋ชจ๋ฐ”์ผ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์œ„ํ•œ ์ผ๋ จ์˜ ๊ฐ•๋ ฅํ•œ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜๋Š” ๊ฐ„๊ฒฐํ•˜๊ณ  ์œ ์—ฐํ•œ Node.js ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ํ”„๋ ˆ์ž„์›Œํฌ์ž…๋‹ˆ๋‹ค.

     

    ๐Ÿ’กExpress๋Š” ์™œ ์จ์š”?

    ๐Ÿ“– ๊ฐ€๋ณ๊ฒŒ ์›น ์„œ๋ฒ„๋ฅผ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค

     

     

     

    Mini-Node Server

    ๐Ÿ“Œ Mini-Node Server ๐Ÿ“์„œ๋ฒ„์‹คํ–‰ node server/basic-server.js ๐Ÿ“– ํ•™์Šต ๋ชฉํ‘œ POST์— ๋ฌธ์ž์—ด์„ ๋‹ด์•„ ์š”์ฒญ์„ ๋ณด๋‚ผ ๋•Œ๋Š” HTTP ๋ฉ”์‹œ์ง€์˜ body(payload)๋ฅผ ์ด์šฉํ•ฉ๋‹ˆ๋‹ค. ์„œ๋ฒ„๋Š” ์š”์ฒญ์— ๋”ฐ๋ฅธ ์ ์ ˆํ•œ ์‘๋‹ต์„ ํด๋ผ์ด์–ธํŠธ๋กœ

    hwantech.tistory.com

     

    ๐Ÿ‘†๐Ÿ‘† mini node server Express๋กœ ๊ตฌํ˜„ ํ•ด๋ณด๊ธฐ

     

    basic.server.js

     

    ๋ž˜ํผ๋Ÿฐ์Šค์—์„œ cors ์„ค์น˜ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— cors ์ด์šฉ

     

    npm install cors

     

    const express = require('express') 
    const app = express()
    const cors = require('cors')
    
    app.use(cors()) // ๋ชจ๋“  ์š”์ฒญ์— cors ํ—ˆ์šฉ
    //npm install cors --save ํ„ฐ๋ฏธ๋„์—์„œ ์„ค์น˜
    app.use(express.json({strict : false}))
    // const jsonParser = express.json({
    //   strict: false
    // })
    // jsonParser๋ฅผ ๋ณ€์ˆ˜๋กœ ์„ ์–ธํ•ด ํ•˜๋‚˜์”ฉ ๋„ฃ์–ด์ค˜๋„ ๋˜๊ณ 
    // ์œ„์ฒ˜๋Ÿผ ๋ชจ๋“  ์š”์ฒญ์— ์ ์šฉํ•  ์ˆ˜๋„ ์žˆ๋‹ค 
    
    const port = 4999 // ํฌํŠธ๋ฒˆํ˜ธ ํ™•์ธ
    
    app.get('/', (req, res) => {
      res.send('hello world')
    })
    
    
    app.post('/lower', (req, res) => {
      res.json(req.body.toLowerCase())
    })
    
    app.post('/upper' , (req, res) => {
      res.json(req.body.toUpperCase())
    })
    
    
    app.listen(port, () => {
      console.log(`Example app listening at http://localhost:${port}`)
    })

     

    ๐Ÿ“Middleware

     

    ๋ฏธ๋“ค์›จ์–ด๋ž€ ์šด์˜์ฒด์ œ์™€ ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ ์‚ฌ์ด์—์„œ ์‹คํ–‰๋˜๋Š” ์†Œํ”„ํŠธ์›จ์–ด์ด๋‹ค.

    ์š”์ฒญ๊ณผ ์‘๋‹ด์˜ ์ค‘๊ฐ„์— ์œ„์น˜ํ•ด์„œ ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•˜๊ฑฐ๋‚˜ ๋‚˜์œ ์š”์ฒญ์„ ๊ฑธ๋Ÿฌ๋‚ธ๋‹ค

    ' ์ž๋™์ฐจ ๊ณต์žฅ์˜ ๊ณต์ •๊ณผ๋„ ๋น„์Šท' , ๋ฏธ๋“ค์›จ์–ด๋Š” Express์˜ ๊ฐ€์žฅ ํฐ ์žฅ์ ์ด๋‹ค

     

    ๋ฏธ๋“ค์›จ์–ด์˜ ๋Œ€ํ‘œ์  ์‚ฌ์šฉ (npm์œผ๋กœ ๋‹ค์šด ๊ฐ€๋Šฅ )

     

    Morgan ์ต์Šคํ”„๋ ˆ์Šค ํ”„๋ ˆ์ž„์›Œํฌ๊ฐ€ ๋™์ž‘ํ•˜๋ฉด์„œ ๋‚˜์˜ค๋Š” ๋ฉ”์‹œ์ง€๋“ค์„ ์ฝ˜์†”์— ํ‘œ์‹œํ•ด์คŒ
    Compression ํŽ˜์ด์ง€๋ฅผ ์••์ถ•ํ•ด์„œ ์ „์†กํ•ด์คŒ
    Session์€ ์„ธ์…˜ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒํ•จ
    Body-parser์€ ํผ์—์„œ ์ „์†ก๋˜๋Š” POST ๊ฐ’์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•จ
    Cookie-parser๋Š” ์ฟ ํ‚ค๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•จ
    Method-override๋Š” REST API์—์„œ PUT๊ณผ DELETE ๋ฉ”์†Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•จ
    Cors ํฌ๋กœ์Šค์˜ค๋ฆฌ์ง„(๋‹ค๋ฅธ ๋„๋ฉ”์ธ ๊ฐ„์˜ AJAX ์š”์ฒญ)์„ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•ด์คŒ
    Multer ํŒŒ์ผ์—…๋กœ๋“œ๋ฅผ ํ•  ๋•Œ ์ฃผ๋กœ ์“ฐ์ž„

     

     

    ๋ฏธ๋“ค์›จ์–ด ์‹คํ–‰

     

    app.set('port', process.env.PORT || 3000)
    
    // app.use() => ๋ชจ๋“  ์š”์ฒญ์— ๋Œ€ํ•ด์„œ ์ด ๋ฏธ๋“ค์›จ์–ด๊ฐ€ ์‹คํ–‰๋œ๋‹ค
    app.use((req,res,next) =>{
      console.log('๋ชจ๋“  ์š”์ฒญ์— ๋‹ค ์‹คํ–‰๋จ')
      next()
    })
    
    app.get('/', (req, res, next) =>{
      console.log('GET, / ์š”์ฒญ์—์„œ๋งŒ ์‹คํ–‰๋จ')
      next()// ๋‹ค๋ฅธ ์š”์ฒญ์„ ๋ณด๋ƒ„
    }),(req,res) => {
      throw new Error('์—๋Ÿฌ๋Š” ์—๋Ÿฌ์ฒ˜๋ฆฌ ๋ฏธ๋“ค์›จ์–ด๋กœ ๊ฐ')
    }
    
    // ์—๋Ÿฌ์ฒ˜๋ฆฌ ๋ฏธ๋“ค์›จ์–ด
    app.use((err, req, res, next) => {
      console.log(err)
      res.status(500).send(err.message) // res.send()๋กœ ์‘๋‹ต์„ ๋ณด๋ƒ„
    })
    
    app.listen(app.get('port'),()=>{
    })

     

     

    ๋ผ์šฐํŒ… 

     

    URL ์š”์ฒญ์— ๋”ฐ๋ฅธ ์‘๋‹ต ์ฒ˜๋ฆฌ๋ฅผ ์˜๋ฏธ

     

    // ์•„๋ž˜ ์ฝ”๋“œ์ฒ˜๋Ÿผ rest API๋“ฑ์˜ ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ๋งค๊ฒŒ๋ณ€์ˆ˜๋กœ ์ฃผ์†Œ๋ฅผ, ๊ทธ ํ›„ ์ฒ˜๋ฆฌํ•  ๋‚ด์šฉ์„ ๋„ฃ์–ด ์ž‘๋™
    
    app.get('/', (req, res) => {
        res.send('hello, world!');
    })

     

     

    Express ์„ค๋ช…

     

    ์ผ๋ฐ˜์ ์œผ๋กœ ์ฒซ ์ค„์—์„œ ๋งˆ์ง€๋ง‰์ค„๋กœ ์ง„ํ–‰

    ๋ฏธ๋“ค์›จ์–ด ์…‹ํŒ… -(์š”์ฒญ์ด ์˜ค๋ฉด)-> ๋ผ์šฐํŠธ -(if X)-> error

    but, ๋ผ์šฐํŠธ๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ณ  ์—๋Ÿฌ์ฒ˜๋ฆฌ๊ฐ€ ์•ˆ ๋˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ์žˆ๋‹ค?

    -> ๋ผ์šฐํŠธ ์•ˆ์— next()๊ฐ€ ๋“ค์–ด์žˆ์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ!

     

    -------------------------------------------------------------------------

     

    ์ด๊ฒƒ๋งŒ ๊ธฐ์–ตํ•˜์ž!

     

    ์„œ๋ฒ„๋ฅผ ์ฒ˜์Œ ์‹คํ–‰ ์‹œํ‚ค๋ฉด ๋ฏธ๋“ค์›จ์–ด ์…‹ํŒ… ๋ถ€๋ถ„์ด ๋™์ž‘

    ๊ทธํ›„ '์ฃผ์†Œ/'๋ฅผ ๋“ค์–ด๊ฐ€๊ฒŒ ๋˜๋ฉด ๋ผ์šฐํŠธ ๋ถ€๋ถ„์ด ์‹คํ–‰๋˜๊ณ  ๋‹ค์‹œ ์š”์ฒญ์„ ๊ธฐ๋‹ค๋ฆผ

    ์ฃผ์†Œ/๊ฐ€ ์•„๋‹Œ ๊ฒฝ์šฐ ๋‹ค๋ฅธ ์ฃผ์†Œ๋กœ ๋“ค์–ด๊ฐ€๋ฉด ๋ผ์šฐํŠธ ์‹คํ–‰ x ์—๋Ÿฌ์ฒ˜๋ฆฌ ๋™์ž‘

     

    ์ด๊ฑธ๋ณด๊ณ  ๋ฏธ๋“ค์›จ์–ด ์‹คํ–‰์„ ๋‹ค์‹œ๋ณด๋ฉด ์ดํ•ด๊ฐ€ ๊ฐ„๋‹ค!

     

    --------------------------------------------------------------------------

     

     

     

     

    ๐Ÿ“๋ฏธ๋“ค์›จ์–ด๊ฐ€ ์ž์ฃผ ์‚ฌ์šฉ๋˜๋Š” ์ƒํ™ฉ

     

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

     

     

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

     

    var myLogger = function (req, res, next) {
      console.log(req.method, req.url);
      next();
    };
    
    app.use(myLogger)
    
    // POSR /upper
    // ๋ชจ๋“  ์š”์ฒญ์— ๋Œ€ํ•ด์„œ ๋ฏธ๋“ค์›จ์–ด๊ฐ€ ๋กœ๊ทธ๊ฐ€ ์ฐํžˆ๊ธฐ ๋•Œ๋ฌธ์—
    // ๋””๋ฒ„๊น… ํ•  ๋•Œ ํŽธ๋ฆฌํ•˜๋‹ค

     

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

     

    node.js๋กœ HTTP body(payload)๋ฅผ ๋ฐ›์„ ๋•Œ์—๋Š” Buffer๋ฅผ ์กฐํ•ฉํ•ด์„œ ๋‹ค์†Œ ๋ณต์žกํ•œ ๋ฐฉ์‹์œผ๋กœ body๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ์—ˆ๋‹ค

     

    let body = [];
    request.on('data', (chunk) => {
      body.push(chunk);
    }).on('end', () => {
      body = Buffer.concat(body).toString();
      // body ๋ณ€์ˆ˜์—๋Š” ๋ฌธ์ž์—ด ํ˜•ํƒœ๋กœ payload๊ฐ€ ๋‹ด๊ฒจ์ ธ ์žˆ์Šต๋‹ˆ๋‹ค.
    });
    
    // ------------------------------------------------------------
    // body-parser ๋ฏธ๋“ค์›จ์–ด๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ด ๊ณผ์ •์„ ๊ฐ„๋‹จํžˆ ์ฒ˜๋ฆฌ
    // ๋‹ค๋ฃฐ ์ˆ˜ ์žˆ๋Š” ๋ฐ”๋”” ํ˜•์‹์€ json, text, buffer ๋งŒ ๊ฐ€๋Šฅ
    
    const jsonParser = express.json()
    
    // ์ƒ๋žต
    app.post('/api/users', jsonParser, function (req, res) {
      // req.body์—๋Š” JSON์˜ ํ˜•ํƒœ๋กœ payload๊ฐ€ ๋‹ด๊ฒจ์ ธ ์žˆ์Šต๋‹ˆ๋‹ค.
    })

     

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

     

    node.js ์ฝ”๋“œ์— CORS ํ—ค๋”๋ฅผ ๋ถ™์ด๋ ค๋ฉด, ์‘๋‹ต ๊ฐ์ฒด์˜ writeHead ๋ฉ”์†Œ๋“œ ๋“ฑ์„ ์ด์šฉํ•˜๊ณ  Access-Control-Allow-* ํ—ค๋”๋ฅผ ๋งค๋ฒˆ ์žฌ์ •์˜ ํ•ด์ค˜์•ผ ํ–ˆ๋‹ค
    ๊ทธ๋ฆฌ๊ณ  OPTIONS ๋ฉ”์†Œ๋“œ์— ๋Œ€ํ•œ ๋ผ์šฐํŒ…๋„ ๋”ฐ๋กœ ๊ตฌํ˜„ํ•ด์•ผ ํ•œ๋‹ค

     

    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()
    }

     

    cos ๋ฏธ๋“ค์›จ์–ด๋ฅผ ์‚ฌ์šฉํ•ด ๊ฐ„๋‹จํžˆ ์ฒ˜๋ฆฌ

     

    // npm 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'})
    })

     

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

     

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

     

    ํ† ํฐ(Token) : ์ฃผ๋กœ ์‚ฌ์šฉ์ž ์ธ์ฆ์—์„œ ์‚ฌ์šฉ 

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

     

     

     

     

     

     

    ๋ฐ˜์‘ํ˜•

    'codeStates front-end > node(server)' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

    ๋Œ“๊ธ€

Designed by Tistory.