[Node.js] Chatter box server SPRINT Review ๐Ÿ’ฏ๏ธ

jungeundelilahLEEยท2020๋…„ 12์›” 29์ผ
0

Node.js

๋ชฉ๋ก ๋ณด๊ธฐ
14/27

goal

โœ“ GET /messages ์š”์ฒญ์€ 200 ์ƒํƒœ ์ฝ”๋“œ๋ฅผ ์‘๋‹ตํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค (162ms)
โœ“ GET /messages ์š”์ฒญ์€ ํŒŒ์‹ฑ ๊ฐ€๋Šฅํ•œ JSON ๋ฌธ์ž์—ด์„ ๋Œ๋ ค์ค˜์•ผ ํ•ฉ๋‹ˆ๋‹ค (37ms)
โœ“ GET /messages ์š”์ฒญ์˜ ์‘๋‹ต์€ ๊ฐ์ฒด์˜ ํ˜•ํƒœ์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค (34ms)
โœ“ GET /messages ์š”์ฒญ์˜ ์‘๋‹ต ๊ฐ์ฒด๋Š” results์— ๋ฐฐ์—ด์„ ํฌํ•จํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค (21ms)
โœ“ ์˜ฌ๋ฐ”๋ฅธ POST /messages ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค (28ms)
โœ“ GET ์š”์ฒญ์‹œ, ์ตœ๊ทผ POST ์š”์ฒญ์„ ํ†ตํ•ด ์ œ์ถœํ•œ ๋ฉ”์‹œ์ง€๊ฐ€ ๊ฒฐ๊ณผ๋กœ ์ „๋‹ฌ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค (31ms)
โœ“ ์กด์žฌํ•˜์ง€ ์•Š๋Š” endpoint๋ฅผ ์š”์ฒญํ•  ๋•Œ์—, 404 ์ƒํƒœ ์ฝ”๋“œ๋ฅผ ์‘๋‹ตํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค (13ms)

Code ๐Ÿ’ฏ๏ธ

๐Ÿ“‚๏ธclient - ๐Ÿ“‚๏ธscript / app.js
ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย - index.html
๐Ÿ“‚๏ธserver - basic-server.js
ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย - request-handler.js

๋ญ ์š”๋Ÿฐ ๋Š๋‚Œ์œผ๋กœ ํŒŒ์ผpath ์ •๋ฆฌ
์ด ์™ธ ์ƒˆ๋กœ ์จ๋ณธ ๊ฒƒ๋“ค๐Ÿ‘‡๏ธ

์ƒˆ๋กœ์šด ๊ฐœ๋…๋“ค์„ ๋งŽ์ด ์ ‘ํ–ˆ๊ณ , ํ•˜๋‚˜์”ฉ ์ฐ์–ด๋ณด๋ฉด์„œ ์–ด๋–ป๊ฒŒ ์ƒ๊ธด๊ฑด์ง€ ํƒ๊ตฌํ–ˆ๋‹ค. ์žฌ๋ฐŒ์—ˆ๋‹ค ใ…Žใ…Ž ์„œ๋ฒ„์™€ ํด๋ผ์ด์–ธํŠธ ์—ฐ๊ฒฐํ•˜๋Š” ๊ฒŒ ์—ญ์‹œ ๋„˜๋‚˜ ์‹ ๊ธฐ ใ…Žใ…Ž
์•„๋ž˜ ์ฝ”๋“œ ๋ณต๋ถ™
ํ—ท๊ฐˆ๋ฆด ๋•Œ๋งˆ๋‹ค ๋‹ค์‹œ ๋ณด๊ธฐ! ๊นƒํ—™์—๋„ ์žˆ๋Š”๋ฐ ๋‚ด๊ฐ€ ์• ์ •ํ•˜๋Š” ๋ธ”๋กœ๊ทธ๋‹ˆ๊นŒ >
<_

์•„ ๊ทธ๋ฆฌ๊ณ  ๋…ธ๋“œ๋ชฌ ์‚ฌ์šฉ์‹œ ํฌํŠธ ์ถฉ๋Œ ์ด์Šˆ...
์ด๊ฑฐ๋•Œ๋ฌธ์— ๊ณ„์† ์—๋Ÿฌ๋‚ฌ๋‹ค...
$ lsof -nP -iTCP:3000
$ kill -9 (PID๋ฒˆํ˜ธ)

app.js

const app = {
  // server: 'http://52.78.206.149:3000/messages',
  server: 'http://127.0.0.1:3000/messages',
  // server: 'http://localhost:3000/messages',

  init: () => {
    app.addEventHandlers();
    app.fetch(json => {
      json.results.forEach(app.renderMessage);
    });
  },
  fetchAndRender: () => {
    app.fetch(data => {
      data.results.forEach(app.renderMessage);
    });
  },
  addEventHandlers: () => {
    let submit = document.querySelector('#send .submit');
    if (submit) {
      submit.addEventListener('submit', app.handleSubmit);
    }
  },
  fetch: callback => {
    window
      .fetch(app.server)
      .then(resp => {
        return resp.json();
      })
      .then(callback);
  },
  send: (data, callback) => {
    window
      .fetch(app.server, {
        method: 'POST',
        body: JSON.stringify(data),
        headers: {
          'Content-Type': 'application/json'
        }
      })
      .then(resp => {
        return resp.json();
      })
      .then(callback);
  },
  clearMessages: () => {
    document.querySelector('#chats').innerHTML = '';
  },
  clearForm: () => {
    document.querySelector('.inputUser').value = '';
    document.querySelector('.inputChat').value = '';
  },
  renderMessage: ({ username, text, date, roomname }) => {
    const tmpl = `<div class="chat">
      <div class="username">${username
        .replace(/</g, '&lt;')
        .replace(/>/g, '&gt;')}</div>
      <div>${text
        .replace(/</g, '&lt;')
        .replace(/>/g, '&gt;')}</div>
      <div>${date}</div>
      <div>${roomname
        .replace(/</g, '&lt;')
        .replace(/>/g, '&gt;')}</div>
    </div>`;

    document.querySelector('#chats').innerHTML =
      tmpl + document.querySelector('#chats').innerHTML;
  },
  handleSubmit: e => {
    e.preventDefault();
    app.clearMessages();
    app.send(
      {
        username: document.querySelector('.inputUser').value,
        text: document.querySelector('.inputChat').value,
        roomname: '์ฝ”๋“œ์Šคํ…Œ์ด์ธ '
      },
      () => {
        app.fetchAndRender();
        app.clearForm();
      }
    );
  }
};

app.init();

basic-server.js

const http = require("http");
const requestHandler = require("./request-handler");

const port = 3000;
const ip = "127.0.0.1";
// const ip = "localhost";

const server = http.createServer(requestHandler);
server.listen(port, ip);

module.exports = server;

request-handler.js (2๊ฐ€์ง€ ๋ฐฉ๋ฒ•)

//todo
//todo 3. GET /messages ์š”์ฒญ์˜ ์‘๋‹ต์€ ๊ฐ์ฒด์˜ ํ˜•ํƒœ์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค (4ms)
//todo 4. GET /messages ์š”์ฒญ์˜ ์‘๋‹ต ๊ฐ์ฒด๋Š” `results`์— ๋ฐฐ์—ด์„ ํฌํ•จํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค (2ms)
//! ๊ฒฐ๊ณผ๊ฐ’ = { results : [ {}, {}, {}....] }
const print = { results : [] }

const requestHandler = function (request, response) {
  // ๊ธฐ๋ณธ CORS ์„ค์ •์ด ๋˜์–ด์žˆ๋Š” ์ฝ”๋“œ ์ž…๋‹ˆ๋‹ค. ์•„๋ž˜์— ์žˆ์Šต๋‹ˆ๋‹ค.
  const headers = defaultCorsHeaders;
  headers["Content-Type"] = "text/plain";

  if (request.method === "OPTIONS") {
    response.writeHead(200, headers)
    response.end()
  }

  // โญ๏ธ์ฒซ๋ฒˆ์งธ ๋ฐฉ๋ฒ•โญ๏ธ
  
  if (request.method === "POST") {
    if (request.url === "/messages") {
      let body = []
      request.on("data", (chunk) => {
          console.log(chunk)
          //! chunk = <Buffer 7b 22 75 73 65 72 6e 61 6d 65 22 3a 22 4a 6f 6e 6f 22 2c 22 74 65 78 74 22 3a 22 44 6f 20 6d 79 20 62 69 64 64 69 6e 67 21 22 7d>
          console.log(body)
          //! body = []
        body.push(chunk)
      }).on("end", () => {
        body = Buffer.concat(body).toString()
          console.log(body) 
          //! body = <Buffer>
          console.log(Buffer)
          //! Buffer = { [Function: Buffer]
          //!             poolSize: 8192,
          //!             from: [Function: from],
          //!             of: [Function: of],
          //!             alloc: [Function: alloc],
          //!             allocUnsafe: [Function: allocUnsafe],
          //!             allocUnsafeSlow: [Function: allocUnsafeSlow],
          //!             isBuffer: [Function: isBuffer],
          //!             compare: [Function: compare],
          //!             isEncoding: [Function: isEncoding],
          //!             concat: [Function: concat],
          //!             byteLength: [Function: byteLength],
          //!             [Symbol(kIsEncodingSymbol)]: [Function: isEncoding] }
          console.log(body) 
          //! body = {"username":"Jono","text":"Do my bidding!"}
        body = JSON.parse(body)
          console.log(body)
          //! body = { username: 'Jono', text: 'Do my bidding!' }
        print.results.push(body) // ๋งŒ๋“  ๊ทธ๋ฆ‡์— ๋„ฃ์–ด์ฃผ๊ธฐ
          
        response.writeHead(201, headers)
        response.end(JSON.stringify(print))
        
      })
    }  else {
      response.writeHead(404, headers)
      response.end()
    }
  
  // โญ๏ธ๋‘๋ฒˆ์งธ ๋ฐฉ๋ฒ•โญ๏ธ

  if (request.method === "POST") {
    if (request.url === "/messages") {
      let body = "";
      request.on('data', (chunk) => {
        body = body + chunk
            console.log(body) 
            //! body = {"username":"Jono","text":"Do my bidding!"} ๐Ÿ‘‰๏ธ ๋‚  ๊ฒƒ์˜ body 
        print.results.push(JSON.parse(body)) // ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋กœ
            console.log(body) 
            //! body = {"username":"Jono","text":"Do my bidding!"} ๐Ÿ‘‰๏ธ parse๋œ body / ์ŠคํŠธ๋ง์œผ๋กœ ํ•ด์„œ๊ทธ๋Ÿฐ์ง€ ๋‹ค๋ฅธ์ ์ด ์—†๋„ค?
            console.log(print.results) 
            //! print.results // print = { results : [{username: 'Jono', text: 'Do my bidding!'}] } ๐Ÿ‘‰๏ธ ๋ฌธ์ œ์—†์ด ์ž˜ ๋“ค์–ด๊ฐ ใ…Žใ…Ž ๊ทผ๋ฐ parseํ•ด์ฃผ์ง€ ์•Š์œผ๋ฉด ์—ญ์Šฌ๋ž˜์‰ฌ ๋ฌธ์ œ๊ฐ€ ์ƒ๊ธธ๊ฑธ?
      }).on('end', () => {
            console.log(print)  
            //! print = { results: [{username: 'Jono', text: 'Do my bidding!'}] }  => โญ๏ธstringify๋œ ๋งˆ์ง€๋ง‰ ๊ฒฐ๊ณผ๊ฐ’โญ๏ธ
        response.writeHead(201, headers)
        response.end(JSON.stringify(print)) // JSON์œผ๋กœ
      })
    } else {
      response.writeHead(404, headers)
      response.end()
    }

  } else if (request.method === "GET") {
    if (request.url === "/messages") {
      response.writeHead(200, headers) 
      response.end(JSON.stringify(print))
      // response.end(print)
          console.log(print)
          //! TypeError [ERR_INVALID_ARG_TYPE]: The "chunk" argument must be one of type string or Buffer. Received type object
    } else {
      response.statusCode=404
      response.end()
    }
  } 

};

const defaultCorsHeaders = {
  "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 // Seconds.
};

module.exports = requestHandler;
profile
delilah's journey

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