프로그래밍 공부/Backend

[Node.js] Mini Node Server / TIL 32 일차

Kevinkb 2021. 10. 26. 16:48

HTTP 트랜잭션

서버 생성

node에 웹 서버를 생성하려면 웹 서버 객체를 만들어야 한다. createServer를 이용한다.

const http = require('http');
const PORT = 5000;
const ip = "localhost";

const server = http.createServer((request, response) => {
  // 여기서 작업이 진행됩니다!
});

이 서버로 오는 http 요청마다 createServer의 콜백 함수가 호출된다. 서버에 http 요청이 오면 node는 트랜잭션을 다루기 위해 요청 핸들러 함수(콜백 함수)를 호출하고 requestresponse 객체를 매개변수로 전달한다.

서버 연결

요청을 실제로 처리하기 위해서는 listen메서드가 서버 객체에서 호출되야 한다.

server.listen(PORT, ip, () => {
  console.log(`http server listen on ${ip}:${PORT}`);
});

메서드, url

요청을 처리하기 위해 request 객체의 유용한 프로퍼티를 사용할 수 있다.

const server = http.createServer((request, response) => {
  console.log(
    `http request method is ${request.method}, url is ${request.url}`
  );

  const { method, url, headers } = request;
  console.log(
    `http request method is ${method}, url is ${url}`
  );
});

요청 바디 받기

POSTPUT 요청을 받을 때 바디 데이터를 받는 방법은 다음과 같다. 핸들러에 전달된 requrest 객체는 ReadableStrem 인터페이스를 구현하고 있는데, 이 스트림에 이벤트 리스너를 등록하거나 다른 스트림을 연결할 수 있다. 바디 데이터는 data, end 이벤트를 이용해 받을 수 있다. 스트림에서 오류가 발생하면 오류를 전달하기 위해 error 이벤트 리스너를 사용한다.

let body = [];
request.on('error', (err) => {
  console.error(err);
}).on('data', (chunk) => {
  body.push(chunk);     // 버퍼 조각들을 전달한다.
  console.log(chuck);  // <Buffer 01 58 82 49 51 25> 
}).on('end', () => {
  body = Buffer.concat(body).toString();  // `body`에 전체 요청 바디가 문자열로 담겨있다.
  // 여기서 헤더, 메서드, url, 바디를 가지게 되었고
  // 이 요청에 응답하는 데 필요한 어떤 일이라도 할 수 있다.
});

HTTP 상태 코드

상태 코드를 따로 설정하지 않으면 응답의 http 상태 코드는 항상 200이다. 따라서 상태코드를 변경하기 위해 statusCode 프로퍼티를 사용한다.

response.statusCode = 404; // 클라이언트에게 리소스를 찾을 수 없다고 알려줍니다.

헤더 설정

헤더는 마지막 설정 값을 보내고 일단 설정이 되면 응답 데이터를 전송할 준비가 되는 것이다.

setHeader 메서드

response.setHeader('Content-Type', 'application/json');
response.setHeader('X-Powered-By', 'bacon');

writeHead 메서드

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,
};
response.writeHead(200, defaultCorsHeader);

응답 바디 전송

end 메서드에 스트림에 보낼 데이터를 작성한다. 응답 바디 전송 전에 상태 코드와 헤더를 설정해야 한다. 또한 response 스트림도 error 이벤트를 발생시킬 수 있기 때문에 에러 처리 코드를 작성한다.

response.on('error', (err) => {  
console.error(err);  
});  
response.writeHead(200, defaultCorsHeader);  
response.end('Hello, World!');

정리

위 내용 통해 서버를 만들면 다음과 같다.

const http = require('http');  
const PORT = 5000;  
const ip = "localhost";

const server = http.createServer((request, response) => {  
  console.log(`http request method is ${request.method}, url is ${request.url}`);
  const { method, url, headers } = request;  
  console.log(`http request method is ${method}, url is ${url}`);

  let body = [];  
  request.on('error', (err) => {  
    console.error(err);  
  }).on('data', (chunk) => {  
    body.push(chunk); // 버퍼 조각들을 전달한다.  
    console.log(chuck); // <Buffer 01 58 82 49 51 25>  
  }).on('end', () => {  
    body = Buffer.concat(body).toString(); // `body`에 전체 요청 바디가 문자열로 담겨있다.

    response.on('error', (err) => {
      console.error(err);
    });

  // 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))
  });  
});

server.listen(PORT, ip, () => {  
  console.log(`http server listen on ${ip}:${PORT}`);  
});

위 서버를 바탕으로 클라이언트의 액션(버튼 클릭)에 따라 각기 다른 HTTP 요청을 서버로 보내고, HTTP 요청에 담아 보낸 단어를 소문자 또는 대문자로 변경된 단어를 응답으로 받아 화면에 보여주는 서버를 만들어 보았다.

const http = require("http");  
const PORT = 5000;  
const ip = "localhost";

const server = http.createServer((request, response) => {  
  if (request.method === "OPTIONS") {  
    response.writeHead(200, defaultCorsHeader);  
    response.end();  
  }  
  else if (requset.method === "POST") {  
    let body = [];  
    request  
    .on("error", err => {  
      console.error(err);  
    })
    .on("data", chunk => {
      body.push(chunk);
    })
    .on("end", () => {
      body = Buffer.concat(body).toString();

      if (request.url === "/upper") {
        response.writeHead(201, defaultCorsHeader);
        response.end(body.toUpperCase());
      }
      else if (request.url === "/lower") {
        response.writeHead(201, defaultCorsHeader);
        response.end(body.toLowerCase());
      }
    });
  } else {  
    response.statusCode = 400;  
    response.end();  
  }  
});

server.listen(PORT, ip, () => {  
  console.log(`http server listen on ${ip}:${PORT}`);  
});

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,  
};  

'프로그래밍 공부 > Backend' 카테고리의 다른 글

[Linux] 사용 권한, 환경 변수  (0) 2021.11.08
[Node.js] Express & Middleware / TIL 33일차  (0) 2021.10.27
TIL 8 일차 2021.09.01  (0) 2021.09.01