HTTP Transection
μμ² μ²λ¦¬
μλ²μ μμ±
λͺ¨λ  node μΉ μλ² μ΄ν리μΌμ΄μ
μ μΉ μλ² κ°μ²΄λ₯Ό λ§λ€μ΄μΌ ν©λλ€.
μ΄λ createServer λ₯Ό μ΄μ©ν©λλ€.
const http = require('http');
const server = http.createServer((request, response) => {
  // Work Process
});
μλ²λ‘ μ€λ λͺ¨λ  HTTP μμ² λ§λ€ createServer μ μ λ¬λ ν¨μκ° νλ²μ© νΈμΆλλ€.
 createServer κ° λ°νν Server κ°μ²΄λ EventEmitter μ΄κ³  server κ°μ²΄λ₯Ό μμ±νκ³  리μ€λλ₯Ό μΆκ°νλ μΆμ½ λ¬Έλ²μ΄λ€.
EventEmitter μ΄λ ?
EventEmitterλ μ΄λ²€νΈ λͺ¨λμ μν΄ μ μ λλ©° μλ‘μ΄ μ΄λ²€νΈκ° μΆκ°λκ±°λ μμ λ λ μ΄λ²€νΈλ₯Ό λ΄λ³΄λ λλ€.
const http = require('http');
const server = http.createServer();
server.on('request', (req, res) => {
  // Work Process
});
HTTP μμ²μ΄ μλ²μ μ€λ©΄ node κ° νΈλμμ
μ λ€λ£¨λ €κ³  request μ response κ°μ²΄λ₯Ό μ λ¬νλ©° μμ² νΈλ€λ¬ ν¨μλ₯Ό νΈμΆ ν©λλ€.
Method, URL, Header μ μ²λ¦¬
μμ²μ μ²λ¦¬ν  λ, μ°μ μ Method μ URL μ νμΈν ν μ΄μ κ΄λ ¨λ μμ
μ μ€νν©λλ€.
 node λ request κ°μ²΄μ λλΆλΆμ νλ‘νΌν°λ₯Ό λ£μ΄λλ―λ‘ κΊΌλ΄μ μ¬μ©νλ©΄ λλ€.
const {method, url} = request;
request κ°μ²΄λ IncomingMessage μ μΈμ€ν΄μ€μ΄λ€.
IncomingMessage Class μ νΉμ§
- HTTP μ μν΄ μμ±λλ€.
 - νΉμ  κ°μ²΄μ 첫λ²μ§Έ λ³μλ‘ μ λ¬λλ μΈμ (
SERVERhttp.ClientRequestrequest eventresponse event) - μλ΅μν λ° ν€λ, λ°μ΄ν° λ±μ μ‘μΈμ€ νλλ° μ¬μ© νλ€.
 
ν€λ λν request κ°μ²΄μμ μ»μ΄μ¨λ€.
const {headers} = request;
const userAgent  = header['user-agent'];
TIP
ν΄λΌμ΄μΈνΈκ° μ€μ ν ν€λ νλ‘νΌν°λ λμλ¬Έμ ꡬλΆμμ΄ μλ¬Έμλ‘λ§ νν λλ€.
μΌλΆ ν€λ μ λ³΄λ₯Ό λ°λ³΅ν΄μ μ€μ νλ©΄ overwrite νκ±°λ csv ννλ‘ κ΅¬μ±λ  μ μλ€. μ΄λ° κ²½μ°μλ rawHeaders λ₯Ό μ¬μ©ν  μ μλ€.
Request Body μ μ²λ¦¬
post νΉμ put μμ²μ νΈλ€λ¬μ μ λ¬λ request κ°μ²΄λ ReadableStream μΈν°νμ΄μ€λ₯Ό ꡬννκ³  μλ€.
μ΄ μ€νΈλ¦Όμ EventListener λ₯Ό λ±λ‘νκ±°λ λ€λ₯Έ μ€νΈλ¦Όμ νμ΄νλ‘ μ°κ²° ν  μ μλ€.
κ° data μ΄λ²€νΈμμ λ°μμν¨ μ²ν¬λ Buffer μ΄λ©° μ΄λ λ¬Έμμ΄ λ°μ΄ν°μ΄λ€.
μ΄λ end μ΄λ²€νΈμμ μ΄μ΄ λΆμΈ λ€μμ λ¬Έμμ΄λ‘ λ§λλκ² κ°μ₯ μ’λ€.
let body = [];
request.on('data', (chunk) => {
  body.push(chunk);
}).on('end', () => {
  // `body` μ μ μ²΄ μμ² λ°λκ° λ¬Έμμ΄λ‘ λ΄κ²¨ μλ€.
  body = Buffer.concat(body).toString();
});
μ€λ₯μ κ΄ν μ²λ¦¬
request μ€νΈλ¦Όμμ μ€λ₯κ° λ°μνλ©΄ error μ΄λ²€νΈκ° λ°ννλ©΄μ μ€λ₯λ₯Ό μ λ¬νλ€.
λ³λμ μ΄λ²€νΈ 리μ€λκ° λ±λ‘λμ΄ μμ§ μλ€λ©΄ μ€λ₯λ₯Ό λ±μΌλ©΄μ Node.js λ₯Ό μ’
λ£μν¨λ€.
request.on('error', (error) => {
  console.error(error.stack);
});
HTTP μμ² μ½λ μ 리
const http = require('http');
http.createServer((request, response) => {
  const {headers, method, url} = request;
  
  let body = [];
  request.on('error', (error) => {
    console.error(error.stack);
  }).on('data', (chunk) => {
    body.push(chunk);
  }).on('end', () => {
    body = Buffer.concat(body).toString();
    /**
     *  ν€λ, λ©μλ, μμ²κ²½λ‘, λ°λ λ±μ κ°μ§κ² λμμΌλ©° 
     *  μ΄ μμ²μ μλ΅νλ μμ
μ μνν  μ μμ΅λλ€.
     */
  })
}).listen(8080);
μ΄ μ½λλ μμ² λ°μ μ μμ§λ§ μμ²ν λλ°μ΄μ€(ν΄λΌμ΄μΈνΈ) μ μλ΅ νλ λ‘μ§μ΄ μκΈ° λλ¬Έμ νμμμμ΄ κ±Έλ¦΄κ² μ λλ€.
μλ΅ μ²λ¦¬
μλ΅ μν μ½λ
λ³λμ μ€μ μ΄ μμΌλ©΄ HTTP μλ΅ μ½λλ 200 μΌλ‘ κ³ μ  λ©λλ€.
μν μ½λλ₯Ό λ³κ²½ νλ €λ©΄ statusCode νλ‘νΌν°λ₯Ό μ€μ ν΄μΌ ν©λλ€.
// 리μμ€λ₯Ό μ°Ύμμ μμ
response.statusCode = 404;
μλ΅ ν€λ μ€μ 
setHeader λ©μλλ‘ ν€λλ₯Ό μ€μ  νλ€.
response.setHeader('Content-Type', 'application/json');
response.setHeader('X-Powered-By', 'bacon');
ν€λ μ€μ  νλ‘νΌν°μ λ/μλ¬Έμλ ꡬλΆμ΄ μλ€.
λͺ μμ  μλ΅ ν€λ λ°μ΄ν° μ μ‘
writeHead λ©μλλ₯Ό μ΄μ©νμ¬ λͺ
μμ μΌλ‘ ν€λ μμ±μ΄ κ°λ₯νλ€.
response.writeHead(200, {
  'Content-Type': 'application/json',
  'X-Powered-By': 'bacon'
});
μλ΅ λ°λ μ μ‘
response κ°μ²΄λ WriteableStream μ΄λ―λ‘ ν΄λΌμ΄μΈνΈλ‘ 보λ΄λ μλ΅ λ°λλ μΌλ°μ μΈ μ€νΈλ¦Ό λ©μλλ₯Ό μ΄μ©νμ¬ μμ± ν©λλ€.
response.write('<html>');
response.write('<body>');
response.write('<h1>Hello, World!</h1>');
response.write('</body>');
response.write('</html>');
response.end();
μ μ½λλ μλμ κ°μ΄ μμ±ν΄λ λμΌνλ€.
response.end('<html><body><h1>Hello, World!</h1></body></html>');
μ€λ₯μ κ΄ν μ²λ¦¬
response μ€νΈλ¦Όλ error μ΄λ²€νΈλ₯Ό λ°μμν¬μ μκ³  λλ‘λ μ΄ μ€λ₯λ μ²λ¦¬ν΄μΌ ν©λλ€.
 request μ€νΈλ¦Όμ λν μ€λ₯μ λμΌνκ² μ μ©μ΄ κ°λ₯ν©λλ€.
νμ¬κΉμ§ μ μ©μ½λ
const http = require('http');
http.createServer((request, response) => {
  const { headers, method, url } = request;
  let body = [];
  request.on('error', (error) => {
    console.error(error);
  }).on('data', (chunk) => {
    body.push(chunk);
  }).on('end', () => {
    body = Buffer.concat(body).toString();
    response.on('error', (error) => {
      console.error(error);
    });
    response.statusCode = 200;
    response.setHeader('Content-Type', 'application/json');
    // μ λμ€μ μ½λλ₯Ό νμ€λ‘ κ°λ₯
    // response.writeHead(200, {'Content-Type': 'application/json'});
    const responseBody = { headers, method, url, body };
    response.write(JSON.stringify(responseBody));
    response.end();
    // μ λμ€μ μ½λλ₯Ό νμ€λ‘ κ°λ₯
    // response.end(JSON.stringify(responseBody));
  });
}).listen(8080);
μμ½ μλ² λ§λ€κΈ°
μμ½μλ²λ μμ² λ°μ λ°μ΄ν°λ₯Ό κ·Έλλ‘ μλ΅μΌλ‘ λ렀보λ΄λ μλ²μ΄λ€.
μμμ νλκ² μ²λΌ μμ² μ€νΈλ¦Όμμμ λ°μ΄ν°λ₯Ό κ°μ Έμ μλ΅ μ€νΈλ¦Όμ μ΄λ€.
const http = require('http');
http.createServer((request, response) => {
  let body = [];
  
  request.on('data', (chunk) => {
    body.push(chunk);
  }).on('end', () => {
    body = Buffer.concat(body).toString();
    response.end(body);
  });
}).listen(8080);
μ μ½λλ₯Ό λ€μ 쑰건μ λ°λΌ μμ½ μλ΅μ 보λ΄λκ²μΌλ‘ μμ νλ€.
- μμ² λ©μλκ° 
POSTμΈ κ²½μ° - URL μ΄ 
/echoμΈ κ²½μ° 
const http = require('http');
http.createServer((request, response) => {
  if (request.method === 'POST' && request.url === '/echo') {
    let body = [];
    request.on('data', (chunk) => {
      body.push(chunk);
    }).on('end', () => {
      body = Buffer.concat(body).toString();
      response.end(body);
    });
  } else {
    response.statusCode = 404;
    response.end();
  }
}).listen(8080);
μμ λ°©λ²μΌλ‘ λΌμ°ν μ νκ³ μμ§λ§
expressνλ μμν¬λrouterλΌμ΄λΈλ¬λ¦¬λ¦ ν΅ν΄μ μ²λ¦¬λ κ°λ₯νλ€.
request κ°μ²΄λ ReadableStream μ΄κ³  response κ°μ²΄λ WriteableStream μ΄λ―λ‘ pipe λ₯Ό μ¬μ©ν  μ μλ€.
const http = require('http');
http.createServer((request, response) => {
  if (request.method === 'POST' && request.url === '/echo') {
    request.pipe('response');
  } else {
    response.statusCode = 404;
    response.end()
  }
}).listen(8080);
μ€λ₯μ κ΄ν μ²λ¦¬
const http = require('http');
http.createServer(request, response) => {
  request.on('error', (error) => {
    console.error(error);
    response.statusCode = 400;
    response.end();
  });
  response.on('error', (error) =>{
    console.error(error);
  });
  if (request.method === 'POST' && request.url === '/echo') {
    request.pipe(response);
  } else {
    response.statusCode = 404;
    response.end();
  }
}).listen(8080);
HTTP μμ²μ λ€μ λμμ΄ κ°λ₯νλ€.
- μμ² νΈλ€λ¬λ‘ HTTP μλ²μ μΈμ€ν΄μ€λ₯Ό μμ± κ°λ₯νκ³ νΉμ  ν¬νΈλ₯Ό μ΄ μ μλ€.
 - request κ°μ²΄μμ Header, Method, URL, Body` λ°μ΄ν°λ₯Ό κ°μ Έμ¬ μ μλ€.
 - URL μ΄λ 
requestκ°μ²΄μ κΈ°λ° λ°μ΄ν°λ‘ λΌμ°ν μ΄ κ°λ₯νλ€. requestκ°μ²΄μμresponseκ°μ²΄λ‘ λ°μ΄ν°λ₯Ό νμ΄νλ‘ μ°κ²° κ°λ₯νλ€.requestμresponseμ€νΈλ¦Ό λͺ¨λμμ μ€νΈλ¦Ό μ€λ₯ μ²λ¦¬κ° κ°λ₯νλ€.