이번에 이해하려는 것
이번에는 Node.js의 대표적인 웹 프레임워크인 Express를 사용해 아주 간단한 서버를 만들어보았다. 단순히 메인 페이지에 문자열을 띄우는 것을 넘어, 주소(Route)에 따라 다른 페이지를 보여주고, 없는 주소로 접속했을 때 '페이지를 찾을 수 없다'는 404 에러를 띄우는 과정까지 코드로 구현해 보았다.
전체 코드
먼저 이번에 작성하고 이해해 본 전체 코드는 다음과 같다.
const express = require('express');
const app = express();
app.get('/', (req, res) => res.send('Hello, World!'));
app.get('/post', (req, res) => '<h1>Home Page</h1>');
app.get('/User', (req, res) => '<h1>User Page</h1>');
app.use((req, res) => {
res.status(404).send('<h1>Page not found</h1>');
})
app.listen(3000, () => {
console.log('server on localhost:3000')
})
코드 흐름 해석
서버 객체 준비하기
이번 코드에서 먼저 본 부분은 Express 모듈을 불러와 앱 객체를 만드는 과정이다.
const express = require('express');
const app = express();
require를 통해 express 모듈을 가져오고, express() 함수를 호출해서 서버 애플리케이션을 담당할 app 객체를 생성한다. 이 app 객체를 통해 앞으로 서버의 여러 가지 설정을 하게 된다.
주소별로 요청 처리하기 (Routing)
서버는 클라이언트가 어떤 주소(경로)로 들어왔는지에 따라 다른 응답을 주어야 한다. 이를 라우팅(Routing)이라고 부르는데, Express에서는 app.get() 메서드를 사용해 아주 직관적으로 처리할 수 있다.
app.get('/', (req, res) => res.send('Hello, World!'));
app.get('/post', (req, res) => '<h1>Home Page</h1>');
app.get('/User', (req, res) => '<h1>User Page</h1>');
- 첫 번째 줄의
'/'경로는 서버의 메인 주소(루트 경로)를 의미한다. 이 경로로 접속하면res.send()메서드를 통해'Hello, World!'라는 일반 텍스트를 응답으로 보낸다. - 그다음 줄부터는
'/post'와'/User'라는 각각의 경로로 들어왔을 때의 동작을 정의해 주었다. 각 경로로 요청이 들어오면 HTML 태그가 포함된 문자열을 응답하도록 작성했다.
여기서 req는 클라이언트가 보낸 요청(Request) 정보를 담고 있고, res는 서버가 클라이언트에게 보낼 응답(Response)을 다루는 객체다.
없는 주소 처리하기 (404 Not Found)
웹사이트에서 설정하지 않은 주소로 접속할 경우를 대비해 에러 처리도 필요하다.
app.use((req, res) => {
res.status(404).send('<h1>Page not found</h1>');
})
이 부분을 보면서 app.get이 아닌 app.use를 쓴 점이 인상적이었다. app.use는 미들웨어(Middleware)를 등록하는 함수인데, 여기서는 별도의 경로 지정 없이 쓰였다. 이렇게 하면 위에서 설정한 '/', '/post', '/User' 경로 어느 곳에도 해당하지 않는 모든 요청이 이 함수로 빠져서 들어오게 된다.
들어온 요청에 대해서는 res.status(404)를 통해 HTTP 상태 코드를 404(찾을 수 없음)로 설정하고, 화면에 '
Page not found
' 문구를 띄워준다.서버 켜기 (Listen)
모든 라우팅 설정이 끝났으면, 실제로 서버가 클라이언트의 요청을 받을 수 있도록 켜주어야 한다.
app.listen(3000, () => {
console.log('server on localhost:3000')
})
listen 함수의 인자로 포트 번호 3000을 넘겨주었다. 이제 로컬 환경에서 3000번 포트로 들어오는 네트워크 요청을 서버가 듣게(Listen) 된다. 서버가 정상적으로 켜지면 콘솔 창에 안내 문구가 출력되어 동작을 확인할 수 있다.
헷갈릴 수 있는 부분
코드를 따라 치면서 주의 깊게 본 부분은 res.send()의 사용 유무였다. 메인 경로에서는 텍스트를 보낼 때 res.send('Hello, World!')를 명시적으로 사용했지만, 그 아래 라우팅 코드들('/post', '/User')은 화살표 함수 내부에 단순히 HTML 문자열만 적혀 있다. 학습 과정에서 메모된 이 코드를 보면, 브라우저에 정상적으로 HTML을 띄우려면 결국 res.send('<h1>Home Page</h1>')의 형태로 클라이언트에게 응답을 보내주도록 고쳐 써야 정상 작동한다는 것을 알 수 있다.
정리
Express를 활용하면 복잡한 서버 설정 없이 직관적인 함수(get, use, listen)만으로 서버 통신을 구현할 수 있다. 주소(Route)에 따라 다른 데이터를 응답해 주고, 정해주지 않은 주소는 app.use를 통해 한 곳에서 모아 404 에러로 처리해 주는 이 전체적인 흐름을 이번 공부를 통해 확실히 이해하게 되었다.