Mini Node Server 과제

현채은·2023년 4월 4일
0

💡 Mini Node Server 과제


  • Node.js의 http 모듈을 이용해 웹서버를 만들어보기
  • Node.js에서 파일을 읽거나 쓰기 위해 fs모듈을 사용하듯이 HTTP요청과 응답을 다루기 위해 HTTP모듈 을 사용한다.
  • 참고하기 좋았던 공식문서 : HTTP 트랜잭션 해부

서버실행

  node server/basic-server.js // basic-server.js 파일을 실행합니다.
  • 서버코드를 수정하고 저장했다면, 프로그램을 매번 다시 실행해야함
  • 매번 파일을 실행하지 않고 npm start 명령어를 이용하는 방법은 없나 ..?
    ➡️ nodemon을 이용하면 가능해 !!
  • nodemon
    • npm install nodemon 으로 설치
    • package.json의 "scripts"에 아래의 코드 추가
     "start": "nodemon server/basic-server.js" 
     // nodemon으로 server/basic-server.js 파일을 실행
    npx nodemon server/basic-server.js
    // npx nodemon server/basic-server.js 파일을 실행

서버 생성

➡️ 모든 node 웹 서버 애플리케이션은 웹 서버 객체를 만들어야 함

  • 이때 createServer이용
const http = require('http');

const server = http.createServer((request,response)) {
  // 여기서 작업이 진행 
});
  • HTTP요청이 서버로 오면 node가 트랜잭션(데이터베이스의 상태를 변화시키기 해서 수행하는 작업의 단위)을 다루려고 requestresponse 객체를 전달
    ➡️ 요청 핸들러 함수를 호출
  • 요청을 실제로 처리하려면 listen 메서드가 server 객체에서 호출 되어야 함
  • 서버가 사용하고자 하는 포트번호를 listen에 전달하면 OK
    • server.listen() : 연결을 수신하는 HTTP 서버를 시작
      ➡️ 이 방법은 server.listen()from 과 동일

메서드, URL, 헤더

📌 메서드와 URL

➡️ 요청을 처리할 때, 우선은 메서드와 URL을 확인

  • 이와 관련된 적절한 작업을 실행
  • Node가 request 객체에 유용한 프로퍼티를 넣어둠 ➡️ easy하게 실행 가능
  • method : HTTP 메서드/동사 (POST, GET, DELETE, PUT .. )
  • url : 전체 URL에서 서버, 프로토콜, 포트번호를 제외한 것 ( 세번째 슬라이스 이후 나머지 전부)
    ex> /upper , /lower

📌 헤더

requestheaders 라는 전용 객체가 존재

  • 클라이언트가 어떻게 헤더를 설정했는지 관계없이 모든 헤더는 "소문자"로만 표현가능

⭐️ 요청 바디

➡️ POSTPUT 요청을 받을 때 애플리케이션에 요청바디는 중요하다.

  • 핸들러에 전달된 request 객체는 ReadableStream 인터페이스를 구현하고 있다.
  • 이 스트림의 dataend이벤트에 이벤트 리스너를 등록해서 데이터를 받을 수 있다.
  • data 이벤트에서 발생시킨 chunkBuffer이다.
    ➡️ 이 chunk 가 문자열 데이터라는 것을 알고 있다면 이 데이터를 배열로 수집한 후 end 이벤트에서 이어붙인 다음 문자열로 만드는 것이 가장 좋음
let body = [];
request.on('data',(chunk) => {
  body.push(chunk);
}).on('end',()=> {
  body = Buffer.concat(body).toString();
  //여기서 `body`에 전체 요청 바디가 문자열로 담겨있음

HTTP 상태코드

➡️ 따로 설정하지 않으면 응답의 HTTP 상태코드는 항상 200

  • 물론 모든 HTTP응답이 이를 보장하는 것은 X
  • 상태코드를 변경하려면 statusCode 프로퍼티를 설정해야함
response.statusCode = 400; // bad request

  • 위 if문을 모두 만족하지 않는 경우 에러처리

💡 fe-sprint-mini-node-server 구현



미리 구현해주신 틀 ( 조건 )에 맞춰서 구현해보기

const http = require('http');
const PORT = 4999 // 서버의 포트번호는 4999로 설정
const ip = 'localhost'
// 서버 구현
const server = http.createServer((req,res) => {
  // 📌 메소드가 options인 경우
  if(req.method === 'OPTIONS'){
  //CORS 설정을 돌려줘야한다
    res.writeHead(200,defalutcorsHeader);
    res.end();
  }
  if ( req.method === 'POST' && req.url === '/upper') {
  // 📌 메소드가 POST이고, url이 /upper 인 경우
    let body = [];
    //.on : 이벤트를 등록하는 메서드
    req.on('data', (chunk) => {
    //chunk는 Buffer형태
      body.push(chunk);
    }).on('end', () => {
    //문자열로 변환
    body = Buffer.concat(body).toString()
    //상태코드와 응답헤더 작성
    res.writeHead(200, defalutcorsHeader);
    // 요청 데이터를 대문자로 변환해서 보낸다
    res.end(body.toUpperCase())
  });
 }
 else if ( req.method === 'POST' && req.url === '/lower') {
  // 📌 메소드가 POST이고, url이 /lower 인 경우
    let body = [];
    //.on : 이벤트를 등록하는 메서드
    req.on('data', (chunk) => {
    //chunk는 Buffer형태
      body.push(chunk);
    }).on('end', () => {
    //문자열로 변환
    body = Buffer.concat(body).toString()
    //상태코드와 응답헤더 작성
    res.writeHead(200, defalutcorsHeader);
    // 요청 데이터를 대문자로 변환해서 보낸다
    res.end(body.toLowerCase())
  });
 }
 else {
 // 📌 위 조건을 모두 만족하지 않는 경우 bad request(400) 에러로 처리
   res.writeHeader(400,defalutcorsHeader);
   res.end();
 }
});
//4999 포트에 서버 활성화
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
};

💡 과제를 하며 궁금했던 점


🧐 PORT를 4999로 설정해주었는데 왜 포트번호가 5500이지 ..?

처음 접한 개념이라 이 부분에 대해 의문이 들었다 ...

✓ 4999는 구현한 서버의 포트번호임 !!

5500은 요청을 보내는 로컬 호스트 주소의 포트번호인 것 ..
➡️ 서로다른 두 출처에서 어떻게 서로 리소스를 주고받는거야 ?
➡️ 💡 CORS를 이용하여 서버 (4999)에 접근할 수 있는 권한을 줬기 때문이야 ❗️

const defaultCorsHeader = {
  'Access-Control-Allow-Origin':'*', // 모든 도메인에서 접근 가능
  'Access-Control-Allow-Method': 'GET, POST, PUT, DELETE, OPTIONS',
  'Access-Control-Allow-Headers': 'Content-Type, Accept',
  'Access-Control-Max-Age': 10
};
profile
프론트엔드 개발자

0개의 댓글