fs를 이용해 서버에 메시지 저장하기

Judo·2021년 1월 3일
0

계획


DB를 안 배운 상황에서 서버에 임시 객체를 만들고 데이터를 저장하고나서 서버를 재시작하면 데이터들이 사라진다. 따라서 file system을 이용해 file에 데이터를 저장할 수 있게 만들기

  1. node에 내장되어 있는 fs module을 이용한다.
  2. 파일에 저장될 데이터를 저장하는 임시객체 resultObj를 만든다.
  3. 서버가 재시작되면 resultObj에 있는 데이터를 사라지므로 서버가 재시작된 경우 파일에 있는 데이터를 읽어와 resultObj에 할당하고 시작한다.
  4. POST 요청이 들어온 경우 들어온 데이터를 file에 저장한다.
  5. GET 요청이 들어온 경우 파일에서 데이터를 읽어와 response에 담아 답한다.

구현 코드


//basic-server.js
/* node 의 모듈들을 불러옵니다. */
const http = require("http");
const requestHandler = require("./request-handler")
const port = 3000;
const ip = "127.0.0.1";
const server = http.createServer(requestHandler);

server.listen(port, ip);
module.exports = server;



//request-handler.js
const fs = require('fs');
//서버가 재시작된 경우 기존에 있던 데이터를 읽어와 resultObj에 넣어놔야 데이터가 사라지지 않는다.
//기존 데이터를 읽어와 resultObj에 넣고 시작
let resultObj = {
  results : []
};
fs.readFile('./message.txt', 'utf8', (err, data) => {
  if (err) throw err;
  //인코딩 형식을 정해주지 않으면 data는 raw Buffer형태로 나옴. 인코딩 형식을 정해줬으니 String으로 나옴
  resultObj = JSON.parse(data);
  //JSON string형태로 파일에 저장되어 있기 때문에 JS객체에 담으려면 파싱을 필요함.
})

const requestHandler = function (request, response) {
  const headers = defaultCorsHeaders;
  headers["Content-Type"] = "application/json";
  response.writeHead(200, headers);

  if (request.method === 'OPTIONS') {
    response.writeHead(200, defaultCorsHeaders);
    response.end();
  } else if (request.method === 'GET') {
    if (request.url === '/messages') {
      //case 2 : fs 이용
      fs.readFile('./message.txt', 'utf8', (err, data) => {
        if (err) throw err;
        console.log(data);
        //인코딩 형식을 정해주지 않으면 data는 raw Buffer형태로 나옴. 인코딩 형식을 정해줬으니 String으로 나옴
        response.end(data);
      })
    } else {
      response.writeHead(404, headers);
      response.end();
    } 
  } else if (request.method === "POST") {
    if (request.url === '/messages') {
      let body = "";
      response.writeHead(201, headers);
      request
        .on('data', chunk => {
          body = body + chunk;
        })
        .on('end', () => {
          //console.log(body);//'{"username": "김코딩", "text": "안녕하세요333"}' => JSON 문자열
          const data = JSON.parse(body);//JSON 문자열로 들어온 데이터를 JS값으로 변환 
          //console.log(data); //{username: '김코딩', text: '안녕하세요333'} => 객체로 변환
          resultObj.results.push(data);
          //console.log(resultObj);
          
          //!fs 이용
          //resultObj를 그냥 저장하면 [object Object] 형태로 나온다. 이 때 JSON.stringify()를 이용하여 String형식으로 변경 후 저장하면 원본 상태를 그대로 유지하면서 저장 가능하다.
          fs.writeFile('./message.txt', JSON.stringify(resultObj), 'utf8', (err) => {
            if (err) throw err;
            console.log('The file has been saved!');
            console.log(JSON.stringify(resultObj))
          });
          //!

          response.end(JSON.stringify(data));
        });
    } else { //POST, messages 로 요청이 들어오지 않았을 떄
      response.writeHead(404, headers);
      response.end();
    }  
  } else {
    response.writeHead(404, headers);
    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;

어려웠던 점


  1. 파일에 저장할 때 {results: []} 형태로 저장되어야 하는데 [object Object] 형태로 저장됨. 이에 따라 저장된 파일을 읽어오는 과정에도 어려움을 겪음

해결


  1. POST 요청이 들어오면 미리 만들어 두었던 resultObj에 데이터를 저장해두는데 이를 그대로 fs.writeFile에 넘겨주면 [object Object] 형태로 들어갔다. 정보를 찾아보니 string형태로 담으면 원본 상태를 유지하면서 저장할 수 있다고 해서 JSON.stringify(resultObj)로 데이터를 저장했다.
 fs.writeFile('./message.txt', JSON.stringify(resultObj), 'utf8', (err) => {
            if (err) throw err;
          });
  1. 위와 같이 저장하면 사진 처럼 저장이 된다. 그래서 GET 요청이 들어왔을 때
fs.readFile('./message.txt', 'utf8', (err, data) => {
   if (err) throw err;
    console.log(data);
   //인코딩 형식을 정해주지 않으면 data는 raw Buffer형태로 나옴. 인코딩 형식을 정해줬으니 String으로 나옴
    response.end(data);
})

위 코드처럼 데이터를 읽어오면 된다.
추가적으로 서버가 재시작되면 resultObj는 초기화되기 때문에 문제가 발생한다. 이를 해결하기 위해 서버가 재시작되면 데이터가 저장된 파일을 읽어와 resultObj에 할당하는 작업을 했다.

let resultObj = {
  results : []
};
fs.readFile('./message.txt', 'utf8', (err, data) => {
  if (err) throw err;
  //인코딩 형식을 정해주지 않으면 data는 raw Buffer형태로 나옴. 인코딩 형식을 정해줬으니 String으로 나옴
  resultObj = JSON.parse(data);
  //JSON string형태로 파일에 저장되어 있기 때문에 JS객체에 담으려면 파싱을 필요함.
})

위와 같이 처리하면 서버가 재시작되더라도 문제가 발생하지 않는다.

profile
즐거운 코딩

0개의 댓글