Jieunny의 블로그
S2) Unit 10. [실습] Mini Node Server 본문
📣 Mini Node Server 만들기
1️⃣ 서버 생성
const http = require('http');
const server = http.createServer((request, response) => {
// 여기서 작업이 진행됩니다!
});
➰ 모든 node 웹 서버 애플리케이션은 웹 서버 객체를 만들어야 하는데, 이 때 createServer를 이용한다.
➰ 이 서버로 오는 HTTP 요청마다 createServer에 전달된 함수가 한 번씩 호출된다.
➰ createServer가 반환한 Server 객체는 EventEmitter이다 (Server 객체를 생성하고 리스너를 추가하는 축약 문법 사용)
➕ EventEmitter 란?
➰ 특정 이벤트에 리스너 함수를 달아서, 이벤트가 발생했을 때 이를 캐치할 수 있도록 만들어진 api
➰ HTTP 요청이 서버에 오면 node가 트랜잭션을 다루려고 request와 response 객체를 전달하며 요청 핸들러 함수를 호출한다.
2️⃣ 요청 바디
➰ 핸들러에 전달된 request 객체는 ReadableStream 인터페이스를 구현하고 있다.
➰ 이 스트림에 이벤트 리스너를 등록하거나 다른 스트림에 연결할 수 있다.
➰ 스트림의 'data' 와 'end' 이벤트에 이벤트 리스터를 등록해서 데이터를 받을 수 있다.
➕ stream 이란?
➰ 스트리밍 데이터로 작업하기 위한 추상적인 인터페이스
➰ 통일된 방식으로 데이터를 다루기 위한 가상의 개념
➰ stream은 읽을 수 있거나, 쓸 수 있거나, 둘 다 가능할 수 있다.
➰ 모든 stream들은 EventEmitter의 인스턴스이므로 이벤트 핸들러를 작성할 수 있다.
let body = [];
request.on('data', (chunk) => {
body.push(chunk);
}).on('end', () => {
body = Buffer.concat(body).toString();
// 여기서 `body`에 전체 요청 바디가 문자열로 담겨있습니다.
});
➰ 각 'data' 이벤트에서 발생시킨 청크는 Buffet이다.
➰ 이 청크가 문자열 데이터라는 것을 알고 있다면, 이 데이터를 배열에 수집한 다음 'end' 이벤트에서 이어 붙인 다음 문자열로 만드는 것이 가장 좋다.
3️⃣ 오류에 대한 간단한 설명
➰ request 스트림의 오류가 발생하면 스트림에서 'error' 이벤트가 발생하면서 오류를 전달핟나.
➰ 이벤트에 리스너가 등록되어 있지 않다면 Node.js 프로그램을 종료시킬 수도 있는 오류를 던질 것이다.
➰ 그러므로 단순히 오류를 로깅만 하더라도 요청 스트림에 'error' 리스너를 추가해야 한다.
request.on('error', (err) => {
// 여기서 `stderr`에 오류 메시지와 스택 트레이스를 출력합니다.
console.error(err.stack);
});
4️⃣ 명시적인 헤더 데이터 전송
➰ 헤더를 작성하는 writeHead 메서드를 이용한다.
➰ 이 메스드는 스트림에 상태 코드와 헤더를 작성한다.
response.writeHead(200, {
'Content-Type': 'application/json',
'X-Powered-By': 'bacon'
});
5️⃣ 응답 바디 전송
➰ 스트림의 end 함수에 스트림에 보낼 데이터의 마지막 비트를 선택적으로 전달 할 수 있다.
// 1
response.write('<html>');
response.write('<body>');
response.write('<h1>Hello, World!</h1>');
response.write('</body>');
response.write('</html>');
response.end();
// 2
response.end('<html><body><h1>Hello, World!</h1></body></html>');
📣 basic-server.js
const http = require('http');
const PORT = 4999;
const ip = 'localhost';
const server = http.createServer((request, response) => {
if(request.method === 'OPTIONS'){
response.writeHead(200, defaultCorsHeader);
response.end();
}
else if(request.method === 'POST'){
if(request.url === '/upper'){
let body = [];
request.on('data', (chunk) => {
body.push(chunk);
}).on('end', () => {
body = Buffer.concat(body).toString().toUpperCase();
// 여기서 `body`에 전체 요청 바디가 문자열로 담겨있습니다.
response.end(body);
});
console.log(body);
}
else if(request.url === '/lower'){
let body = [];
request.on('data', (chunk) => {
body.push(chunk);
}).on('end', () => {
body = Buffer.concat(body).toString().toLowerCase();
response.end(body);
});
}
}
else{
request.on('error', (err) => {
// 여기서 `stderr`에 오류 메시지와 스택 트레이스를 출력합니다.
console.error(err.stack);
});
}
// console.log(
// `http request method is ${request.method}, url is ${request.url}`
// );
response.writeHead(200, defaultCorsHeader);
// response.end('hello mini-server sprints');
});
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
};
📣 시연 화면
📚 참고
HTTP 트랜잭션 해부 https://nodejs.org/ko/docs/guides/anatomy-of-an-http-transaction/
'CodeStates > Training' 카테고리의 다른 글
S2) Unit 11. [실습] Coz’ Mini Hackathon (아고라스테이츠 서버) (0) | 2023.02.09 |
---|---|
S2) Unit 10. [실습] StatesAirline Server (0) | 2023.02.08 |
S2) Unit 9. [실습] StateAirline Client (0) | 2023.02.03 |
S2) Unit 6. [실습] React Twittler State & Props (0) | 2023.01.27 |
S2) Unit3. [실습] fetch API (0) | 2023.01.19 |