HTTP Transaction

Vorhandenheit ·2021년 10월 27일
0

JS/Node 

목록 보기
21/63

HTTP Transaction

클라이언트가 웹서버와 리소스를 주고받기 위해 HTTP 형태로, 요청 명령과 응답 결과로 구성되어있다.

1. 서버 생성

모든 웹 서버 애플리케이션(WAS)는 웹 서버 객체를 만들어야합니다. 이때 createServer를 이용

const http = require('http') // 서버를 만드는 모듈을 불러옴

const server = http.createServer((request, response) => {
}) //서 버를 만드는 메소드

이 서버로 오는 HTTP 요청마다 createServer에 전달된 함수가 한 번씩 호출되어집니다.
createServer가 반환한 server객체는 EventEmitter이고 여기서는 server 객체를 생성하고 리스너를 추가하는 축약 문법을 사용

const server = http.createServer();
server.on('request', (request, response) => {

})

HTTP 요청이 서버에 오면 node가 트랜잭션을 다루기위해 request와 response 객체를 전달하고 요청 핸들러 함수를 호출합니다.

2. 메서드, url, 헤더

const {method, url} = request; // 비구조화 할당
//request.method, request.url을 의미

method는 일반적인 HTTP 메서드/동사
url은 전체 url에서 서버, 프로토콜, 포트를 제외한 것 3번쨰 슬래시 이후에 나머지 전부

const {header} = request;
const userAgent = headers['user-agent']


requestheaders라는 전용 객체가 있음
모든 헤더는 소문자로만 표현해야함

3. 요청 바디

let body = [];
request.on('data', (chunk) => {
	body.push(chunk);
}).on('end', () => {
	body = Buffer.concat(body).toString();
})

핸들러에 전달된 request의 객체는 ReadableStream 인터페이스를 구현하고 있습니다.
이 스트림에 이벤트 리스너를 등록하거나 다른 스트림에 파이프로 연결할 수 있습니다.
스트림의 'data'와 'end'이벤트에 이벤트 리스너를 등록해서 데이터를 받을 수 있습니다.

각 'data'이벤트에서 발생시킨 청크는 Buffer, 이 데이터를 배열에 수집한 다음 'end'이벤트에서 이어 붙인 다음 문자열로 만드는 것이 가장 좋음!

4. 오류에 대한 간단한 설명

request.on('error', (err) => {
	console.error(err.stack)
})

request 객체가 ReadableStream이므로 EventEmitter 이기도하고 오류가 발생했을 때 EventEmitter처럼 동작

request 스트림의 오류가 발생하면 스트림에서 'error' 이벤트가 발생하면서 오류를 전달
이벤트에 리스너가 등록되어 있지 않다면 Node.js프로그램을 종료시킬 수도 있는 오류를 던질 것

const http = require('http');

http.createServer((request, response) => {
	const { headers, method, url } = request;
  let body = []
  request.on('error', (err) => {
  	console.error(err);
  }).on('data', (chunk) => {
  	body.push(chunk);
  }).on('end', () => {
  	body = Buffer.concat(body).toString()
  })
}).listen(8000)// 이 서버를 활성화하고 8000 포트를 받음

HTTP 상태 코드

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

헤더를 여러 번 설정한다면 마지막에 설정한 값을 보냄

1. 명시적 헤더 데이터 전송

response.wrtieHead(200, {
'Content-Type' : 'applicaton/json',
'X-Powered-By' : 'bacon'
});

2.응답 바디 전송

response.write('<html>');
response.write('<body>');
response.write('<h1>Hello, World!</h1>');
response.write('</body>');
response.write('</html>');
response.end();

response 객체는 WritableStream이므로 클라이언트로 보내는 응답 바디는 일반적인 스트림 메서드를 작성

3. 오류에 대한 추가 설명

response 스트림도 'error'이벤트를 발생시킬 수 있고, 때로 이 오류를 처리해야함
request 스트림 오류에 대한 모든 설명 여기에도 적용

3. 지금까지 배운 내용 사용

사용자가 서버에 보낸 모든 데이터를 다시 보내는 서버

const http = require('http');

http.createServer((request, response) => {
  const { headers, method, url } = request;
  let body = [];
  request.on('error', (err) => {
    console.error(err);
  }).on('data', (chunk) => {
    body.push(chunk);
  }).on('end', () => {
    body = Buffer.concat(body).toString();
    // 여기서부터 새로운 부분입니다.

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

    response.statusCode = 200;
    response.setHeader('Content-Type', 'application/json');
    
    const responseBody = {headers, method, url, body}
    response.write(JSON.stringify(responseBody));
    response.end();
  });
}).listen(8000)

4 에코 서버예제

에코 서버는 요청 받은 데이터를 그대로 응답으로 돌려보내는 서버

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

간략화
request 객체는 ReadableStream이고 reponse 객체는 WritableStream임
데이터를 한 스트림에서 다른 스트림으로 직접 연결하는 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);

스트림에서 오류를 처리하기 위해 오류를 stderr에 로깅 Bad Request를 의미하는 400상태 코드를 보낼 것

const http = require('http');

http.createServer((request, response) => {
	request.on('error', (err) => {
      console.error(err)
      response.statusCode = 400;
      response.end();
    })
     response.on('error', (err) => {
     	console.error(err)
     });
  	if (request.method === 'POST'&& request.url === '/echo') {
    	request.pipe(response);
    }
  	else {
    	response.statusCode = 404;
      	response.end();
    }
}).listen(8000);
  • 핸들러 함수로 HTTP 서버의 인스턴스를 생성하고 특정 포트로 서버를 열수 있어야함
  • request 객체에서 url , 메서드, 바디 데이터를 가져올 수 있음
  • url 이나 request 객체의 데이터에 기반을 둬서 라우팅 할 수 있어야함
  • response 객체로 헤더, HTTP 상태 코드, 바디 데이터를 보낼 수 있음
  • request 객체에서 response 객체로 데이터를 파이프로 연결할 수 있음
  • request와 response 스트림 모두에서 스트림 오류를 처리할 수 있음
profile
읽고 기록하고 고민하고 사용하고 개발하자!

0개의 댓글