Back to all posts

Node.js로 HTTP 서버 만들고 URL 경로별로 다른 페이지 응답하기

Node.js의 http 모듈과 url 모듈을 사용해 로컬 서버를 열고, 요청 경로(path)에 따라 각각 다른 HTML 페이지를 반환하는 라우팅 흐름을 공부했습니다.

2026년 05월 07일3

시작하며

이번에는 Node.js에서 제공하는 기본 모듈만 사용해서 직접 서버를 띄워보았다. 브라우저에서 주소를 입력하고 들어갔을 때, 어떤 경로를 요청하느냐에 따라 서버가 다른 응답을 주도록 만드는 것이 이번에 이해하려는 핵심이었다.

전체 코드

작성하며 이해한 전체 코드는 다음과 같다. 코드 안에는 공부하며 남겨둔 단서들이 주석으로 함께 적혀 있다.

  
  
const http = require('http');  
const url = require("node:url");  
  
// localhost -> 127.0.0.1 -> loop back -> 서버를 실행한 컴퓨터  
const host = 'localhost';  
const port = 3000;  
  
// req -> request -> 요청  
// res -> response -> 응답  
const server =  http.createServer((req, res) => {  
    const path = url.parse(req.url).pathname;  
  
    if(path === '/') {  
        res.writeHead(200, {'Content-Type': 'text/html'});  
        res.end('<h1>Home Page</h1>');  
    } else if (path === '/about') {  
        res.writeHead(200, {'Content-Type': 'text/html'});  
        res.end('<h1>About Page</h1>');  
    } else if (path === '/contact') {  
        res.writeHead(200, {'Content-Type': 'text/html'});  
        res.end('<h1>Contact Page</h1>');  
    } else {  
        res.writeHead(404, {'Content-Type': 'text/html'});  
        res.end('<h1>404 Not Found</h1>');  
    }  
});  
  
server.listen(port, host, () => {  
    console.log(`server running ${host}:${port}`)  
});

서버를 띄우기 위한 기본 주소 설정

이번 코드에서 먼저 본 부분은 서버가 어디서, 어떤 문(port)으로 들어오는 요청을 받을지 정하는 부분이다.

주석에 적힌 내용을 보면, localhost127.0.0.1이라는 IP 주소를 가리키며, 이는 곧 네트워크상에서 '서버를 실행한 컴퓨터 자기 자신'을 의미하는 루프백(loop back) 주소임을 알 수 있다. 여기에 port를 3000번으로 지정해서 외부가 아닌 내 컴퓨터의 3000번 포트로 들어오는 통신을 확인하겠다는 뜻으로 이해했다.

요청(req)과 응답(res) 객체 이해하기

http.createServer 안에는 (req, res)라는 두 가지 인자가 넘어온다. 주석에서 확인한 것처럼 req는 클라이언트가 보낸 요청(request)을, res는 서버가 보낼 응답(response)을 담당하는 객체다.

이 중에서 이번에 집중한 것은 req 객체 안에 있는 URL 정보였다. 브라우저가 어떤 주소로 접속했는지 알아야 각기 다른 페이지를 보여줄 수 있기 때문이다. url.parse(req.url).pathname 코드를 사용해 주소창의 전체 URL에서 경로(path) 부분만 따로 떼어내었다.

경로(path)에 따른 라우팅 흐름

이제 떼어낸 경로(path)를 바탕으로, 요청이 들어올 때마다 조건문(if / else if)을 통해 서버가 다르게 반응하도록 만들었다.

  • / 로 들어오면 Home Page를 보여주고,
  • /about 으로 들어오면 About Page를,
  • /contact 로 들어오면 Contact Page를 보여준다.

이때 각 조건문 안에서 res.writeHead를 사용해 상태 코드(200)와 문서 형식(text/html)을 브라우저에 미리 알려주었다. 그다음 res.end를 통해 실제 보여줄 HTML 문자열을 담아 응답을 마무리했다. 만약 설정한 경로 외의 다른 주소로 들어온다면, 404 상태 코드와 함께 '404 Not Found' 페이지를 응답하도록 예외 처리도 함께 추가해 두었다.

서버 실행 및 대기(listen)

마지막으로 모든 설정이 끝난 서버는 server.listen을 통해 실제로 요청을 받을 수 있는 상태가 된다.

코드 마지막 줄의 listen 함수는 앞서 정해둔 porthost에서 들어오는 신호를 계속 기다리게 한다. 이때 콜백 함수가 실행되면서 콘솔창에 서버가 정상적으로 켜졌다는 메시지(server running localhost:3000)가 출력된다. 서버는 이 상태로 계속해서 들어오는 요청을 기다리며, 요청이 올 때마다 위에서 만든 경로별 조건문을 수행하게 된다.

정리

전체 흐름을 정리하면 다음과 같다.

  1. 서버가 내 컴퓨터의 3000번 포트에서 요청을 기다린다.
  2. 브라우저에서 주소를 입력해 요청이 들어온다.
  3. 서버는 요청(req) 객체에서 URL 경로를 파악한다.
  4. 경로에 맞는 HTML 콘텐츠를 작성하여 응답(res) 객체에 담아 보낸다.
  5. 일치하는 경로가 없다면 404 에러 페이지를 응답한다.

이 과정을 통해, Express 같은 프레임워크 없이도 순수 Node.js 모듈만으로 클라이언트의 요청을 받아 분기 처리하는 기본적인 라우팅 구조를 어떻게 구성하는지 이해할 수 있었다.