Node.js 백엔드 스터디(3) - Node.js와 http 객체로 서버 만들기
1. 예제 연습 1 - 무조건 OK를 반환하는 서버
아래 코드는 createServer로 서버 인스턴스를 생성하고, 그 뒤에 listen( ) 함수를 붙여 localhost:3000 요청한 모든 클라이언트에 OK를 응답한다. text/html은 텍스트를 html로 해석하겠다는 의미로, 응답 헤더를 설정하였다.
const http = require("http");
const server = http.createServer((req, res) => {
res.setHeader("Content-Type", "text/html"); // 1) 응답 헤더 설정
res.end("OK") // 2) OK를 응답하고 종료
})
server.listen("3000", () => console.log("OK 서버 시작")); // 3) 접속 대기
2. 예제 연습 2 - 라우터 만들기
아래코드는 서로 다른 URL 경로( 1) localhost:3000/user , 2) localhost:3000/feed )로 들어오는 요청에 대해 다른 응답을 주는 코드이다.
- 순서 1. url 모듈을 로딩하고, url 모듈을 사용해 요청(req)으로 받은 url의 pathname을 받는다.
const http = require("http");
const url = require("url"); // 1) 모듈을 로딩
http
.createServer((req, res) => {
const path = url.parse(req.url, true).pathname; // 2) 패스명 할당
console.log(path);
res.setHeader("Content-Type", "text/html");
})
.listen("3000", () => console.log("라우터를 만들어보자!"));
- 순서 2. pathname을 보고 3가지 결과로 응답한다.
const http = require("http");
const url = require("url"); // 1) 모듈을 로딩
http
.createServer((req, res) => {
const path = url.parse(req.url, true).pathname; // 2) 패스명 할당
// console.log(path);
res.setHeader("Content-Type", "text/html");
if (path === "/user") {
res.end("[user] name : andy, age: 30"); // 3) /user 결괏값 설정
} else if (path === "/feed") {
res.end(`<ul>
<li>picture1</li>
<li>picture2</li>
<li>picture3</li>
</ul>
`); // 4) /feed에 대한 결괏값 설정
} else {
res.statusCode = 404;
res.end("404 page not found"); // 5) 결괏값으로 에러 메시지 설정
}
})
.listen("3000", () => console.log("라우터를 만들어보자!"));
- 순서 3. 아래와 같이 리팩토링할 수 있다.
const http = require("http");
const url = require("url");
http
.createServer((req, res) => {
const path = url.parse(req.url, true).pathname;
res.setHeader("Content-Type", "text/html");
if (path === "/user") {
user(req, res); // 1) user() 함수 콜
} else if (path === "/feed") {
feed(req, res); // 2) feed() 함수 콜
} else {
notFound(req, res); // 3) notFound() 함수 콜
}
})
.listen("3000", () => console.log("라우터를 만들어보자!"));
const user = (req, res) => {
res.end("[user] name : andy, age: 30");
}
const feed = (req, res) => {
res.end(`<ul>
<li>picture1</li>
<li>picture2</li>
<li>picture3</li>
</ul>`);
}
const notFound = (req, res) => {
res.statusCode = 404;
res.end("404 page not found");
}
3. 예제 연습 3 - 동적으로 응답하기
user 함수를 아래와 같이 수정하여, url로 전달받은 쿼리 스트링을 받아 응답하게 한다.
const user = (req, res) => {
// 1. 쿼리 스트링 데이터를 userInfo에 할당
const userInfo = url.parse(req.url, true).query;
// 2. 결괏값으로 이름과 나이 설정
res.end(`[user] name : ${userInfo.name}, age : ${userInfo.age}`);
// res.end("[user] name : andy, age: 30");
}
4. 예제 연습 4 - 맵을 사용해서 다양한 분기 관리하기
위 예제코드는 3개 함수(user(), fee(), notFound())뿐이다. 만약 이런 함수가 100개가 넘어간다면, 유지보수하기 어려울 수 있다. 맵을 사용해서 분기문을 조금더 깔끔하게 아래와 같이 수정할 수 있다. 자바스크립트의 in 연산자와 맵을 사용해 아주 간단하게 URL 라우팅을 할 수 있다.
const http = require("http");
const url = require("url");
http
.createServer((req, res) => {
const path = url.parse(req.url, true).pathname;
res.setHeader("Content-Type", "text/html");
if (path in urlMap) { // 1) urlMap에 path가 있는지 확인
urlMap[path](req, res); // 2) urlMap에 path값으로 매핑된 함수 실행
} else {
notFound(req, res)
}
})
.listen("3000", () => console.log("라우터를 만들어보자!"));
const user = (req, res) => {
const userInfo = url.parse(req.url, true).query;
res.end(`[user] name : ${userInfo.name}, age : ${userInfo.age}`);
}
const feed = (req, res) => {
res.end(`<ul>
<li>picture1</li>
<li>picture2</li>
<li>picture3</li>
</ul>`);
}
const notFound = (req, res) => {
res.statusCode = 404;
res.end("404 page not found");
}
// 3) 라우터 규칙 매킹키로 path가 들어가고 값에 함수를 할당
const urlMap = {
"/": (req, res) => res.end("Home"),
"/user": user,
"/feed": feed
}
참고
다음에 다루게 될 것
- Node.js와 익스프레스로 웹 애플리케이션 서버 구현
댓글남기기