목적: HTTP가 어떻게 작동하는지 ?
createServer
사용
node 웹 서버 어플리케이션은 웹 서버 객체를 만들어야 한다. 아래와 같이 만든다.
const http = require('http');
const server = http.createServer((request, response) => {
// 여기서 작업이 진행됩니다!
});
HTTP 모듈
createServer
에 전달된 함수가 한 번씩 호출됩니다.request
와 response
객체를 전달하며 요청 핸들러 함수를 호출한다.Server객체
createServer
가 반환한 Server 객체는 EventEmitter이고, 여기서는 server 객체를 생성하고 리스너를 추가하는 축약 문법을 사용한 것입니다.request
안에 여러 객제가 있다.request
는 IncomingMessage의 인스턴스 이면서 ReadableStream 이다.const { method, url } = request;
<What is IncomingMessage??>
An IncomingMessage object is created by http.Server or http.ClientRequest and passed as the first argument to the 'request' and 'response' event respectively. It may be used to access response status, headers and data.
메서드 / url
여기서 method는 항상 일반적인 HTTP 메서드/동사가 될 것입니다. url은 전체 URL에서 서버, 프로토콜, 포트를 제외한 것으로, 세 번째 슬래시 이후의 나머지 전부라고 볼 수 있습니다.
헤더(모든헤더는 소문자로만 표현된다)
const { headers } = request;
const userAgent = headers['user-agent'];
request 객체는 ReadableStream 인터페이스를 구현하고 있습니다.
ReadableStream
Readable streams are an abstraction for a source from which data is consumed.
request
에 이벤트 리스너를 등록하거나 다른 스트림에 파이프로 연결할 수 있습니다.
request
의 'data'와 'end' 이벤트에 이벤트 리스너를 등록해서 데이터를 받을 수 있습니다.
let body = [];
request.on('data', (chunk) => {
body.push(chunk);
}).on('end', () => {
body = Buffer.concat(body).toString();
// 여기서 `body`에 전체 요청 바디가 문자열로 담겨있습니다.
});
각 'data' 이벤트에서 발생시킨 청크는 Buffer
입니다. 이 청크가 문자열 데이터라는 것을 알고 있다면 이 데이터를 배열에 수집한 다음 'end' 이벤트에서 이어 붙인 다음 문자열로 만드는 것이 가장 좋습니다.
(항상 오류는 발생할 수 있다는 것을 명심하고 오류를 처리해야 합니다.)
request.on('error', (err) => {
// 여기서 `stderr`에 오류 메시지와 스택 트레이스를 출력합니다.
console.error(err.stack);
});
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();
// 여기서 헤더, 메서드, url, 바디를 가지게 되었고
// 이 요청에 응답하는 데 필요한 어떤 일이라도 할 수 있게 되었습니다.
});
}).listen(8080); // 이 서버를 활성화하고 8080 포트로 받습니다.
response
객체가 없기때문에 요청에 응답하지 않습니다. 클라이언트에서 요청만 보내고 받을게 없어서 타임아웃에 걸리게 된다.response - ServerResponse의 인스턴스이면서 WritableStream입니다
기본 HTTP 상태코드 항상 200
상태 코드를 변경하려면 statusCode
프로퍼티를 설정해야 합니다.
response.statusCode = 404; // 클라이언트에게 리소스를 찾을 수 없다고 알려줍니다.
response.setHeader('Content-Type', 'application/json');
response.setHeader('X-Powered-By', 'bacon');
writeHead
메서드가 있습니다. 이 메서드는 스트림에 상태 코드와 헤더를 작성합니다.response.writeHead(200, {
'Content-Type': 'application/json',
'X-Powered-By': 'bacon'
});
response
객체는 WritableStream
이므로 클라이언트로 보내는 응답 바디는 일반적인 스트림 메서드를 사용해서 작성합니다.response.write('<html>');
response.write('<body>');
response.write('<h1>Hello, World!</h1>');
response.write('</body>');
response.write('</html>');
response.end();
end 함수에 스트림에 보낼 데이터의 마지막 비트를 선택적으로 전달할 수 있다.
response.end('<html><body><h1>Hello, World!</h1></body></html>');
아래 원본 사이트에서 예제를 보면서 다시한번 확인해보자.
원본: https://nodejs.org/ko/docs/guides/anatomy-of-an-http-transaction/
참고: https://close-up.tistory.com/entry/Nodejs-HTTP-%EB%AA%A8%EB%93%88