TIL - Server Side HTTP Transaction2

김수지·2019년 12월 5일
0

TILs

목록 보기
14/39
post-custom-banner

Today What I Learned

Javascript를 배우고 있습니다. 매일 배운 것을 이해한만큼 정리해봅니다.


1. chatter box server 구축

  1. 오늘은 이틀 전 Fetch API를 이용해 만들었던 'chatter box'라는 채팅 클라이언트의 서버를 구축했다. 이로써 클라이언트 사이드와 서버 사이드를 양쪽으로 구현해보면서 http transaction을 손으로 쳐보고 눈으로 확인해볼 수 있었다.
    내일은 드디어 express를 이용한 리팩토링을 진행할 예정이다.
    서버 사이드.... 어려운데 한 번 깨우치고 나면 정말 재미있다ㅎ

  2. 중점적으로 익힌 내용

    • 서버는 클라이언트의 요청에 무조건 응답을 해야 한다. 올바른 요청에 대한 적절한 response 혹은 잘못된 요청이더라도 http status code 등으로 잘못되었음을 응답해주어야 한다. (1 요청, 1응답)
    • response.end()는 서버를 구성하는 함수의 끝이 아니기 때문에 요청을 잘 분기하여 대응해야 한다. response.end()와 함께 함수를 끝내기 위해서는 break, return, throw 등을 활용해야 한다.
    • client - server 사이의 통신(라우팅)은 JSON string 형태로 이루어진다. 따라서 요청을 보낼 때에도 JSON.stringify를 활용해야 하고, server 단에서 수신 완료한 데이터를 가공하거나 추가 작업을 진행을 할 경우에는 파싱하여 js 객체 형태로 작업을 진행한다. 그러나 다시 client로 응답을 보내야 할 때는 다시 JSON.stringify를 활용하여 라우팅 해야 한다.
  3. 고전했던 부분

    • server 단에서의 전달 받은 데이터를 data storage로 저장하는 과정에서 parsing을 주고, 다시 이에 대한 응답을 client로 보낼 때에는 다시 JSON.stringify 해줘야 하는 부분.
    • 그래도 어제 한 번 해봤다고 오늘은 훨씬 수월하게 구현했다 :)
  4. Routing, Stream객체, Buffer, Chunk 개념 정리

    • 어제도 node.js 공식 문서를 읽으면서 개념 정리를 해봤지만 오늘 다시 한 번 routing 과정을 말로 정리해본다.
    • client에서 fetch API로 POST 요청을 보내면서 body 부분에 서버로 보낼 데이터를 담아 JSON string으로 전송한다.
    • 이 데이터는 2진수로 변환되고(compile), 2진수 조각들이 물리적인 랜선을 타고 서버의 라우팅에 순차적으로 도착한다.
    • 여기서 2진수 조각 단위를 chunk로 보면 된다. chunk들은 순차적으로 Buffer라는 곳에 쌓인다.
    • 여기서 쪼개진 chunk를 다시 합치는 과정이 매우 중요하다.
    • 방법 1) string 형태이므로 계속해서 string에 더하는 방법
      let body = "";
      request.on("data", chunk
              => {body += chunk;})
      .on("end", ()
         => { //data storage에 추가
      });
    • 방법 2) 객체에 계속 chunk를 push한 뒤 마지막에 join하는 방법
      let body = [];
      request.on("data", chunk
              => {body.push(chunk);})
      .on("end", ()
       => { //data stroage에 추가
      });
  5. JSON 처리 관련 에러

    • uncaught(in promise) SyntaxError: unexpected token...
    • 이 에러는 JSON.parse 처리하려는 값이 JSON 형태가 아닐 때 나오는 에러이다.
      이러한 에러가 발견되면 JSON 파싱을 꼭 찾아보자!
    • 이런 종류의 에러 나는게 너무 짜증나서 영상도 찾아봄... ㅎ https://www.youtube.com/watch?v=RcEmaTVIE24

2. Code Review

  1. 어제 만든 mini server와 비슷한 형태로 chatter box server를 구축했다.
    다만 이번에는 post 요청에 맞춰서 전달 받은 정보를 data storage에 저장해주고(db는 아직 안 배워서 그냥 data.js에 담는 단계), 등록 처리에 대한 값을 다시 client로 보내주는 역할이 바뀌었다. get 요청도 마찬가지로 data storage의 정보를 다시 client로 전달해주는 역할이 추가되었다.
  2. 오늘은 작성에 급급했지만 리팩토링을 한다면 post, get 등의 요청이 반복적으로 이뤄질 것을 생각해서 함수로 만들어 따로 js에 넣어두고 라이브러리처럼 사용해보는 방향과 file system에 저장시키는 등을 추가해보고 싶다.(다음 솔로데이 때 한 번 해보기로...)
    let { chats, idNum } = require("./data.js");
    const requestHandler = function(request, response) {
    const { method, url } = request;
    let body = [];
    let date;
    
    console.log("Serving request type " + request.method + " for url " + request.url);
    let statusCode = 200;
    let newChat = {};
    
     const headers = defaultCorsHeaders;
    // 응답 헤더에 응답하는 컨텐츠의 자료 타입을 헤더에 기록
    headers["Content-Type"] = "text/plain";
    
     if (method === "OPTIONS" && url === "/classes/messages") {
       //CORS pre flight 확인
         statusCode = 204;
         response.writeHead(statusCode, headers);
         response.end();
    } else if (method === "GET" && url === "/classes/messages") {
        // get 대응
        request.on("error", err => {
          console.err(err);
        });
          response.on("error", err => { console.err(err);});
          statusCode = 200;
          response.writeHead(statusCode, headers);
          response.end(JSON.stringify(chats));
        } else if (method === "POST" && url === "/classes/messages") {
      // post 대응
        request
          .on("error", err => {console.err(err);})
          .on("data", chunk => {
            body.push(chunk);
            date = JSON.stringify(new Date());
          })
          .on("end", () => {
            newChat = JSON.parse(Buffer.concat(body).toString());
            idNum++;
            newChat["id"] = idNum;
            newChat["date"] = date;
            chats.results.push(newChat);
            console.log(newChat);
          });
            response.on("error", err => {console.error(err);});
            statusCode = 201;
            response.writeHead(statusCode, headers);
            response.end(JSON.stringify({ id: idNum }));
         } else {
            //get, post, options 아닐 때 대응
            statusCode = 404;
            response.writeHead(statusCode, headers);
            response.end("error");
         }
    }
profile
선한 변화와 사회적 가치를 만들고 싶은 체인지 메이커+개발자입니다.
post-custom-banner

0개의 댓글