[Node.js] 익스프레스 - 간단한 웹 서버 시작하기

http 모듈만 사용한 웹 서버를 만들 때는 많은 것들을 직접 만들어야 한다. 이를 해결하기 위해 만들어진 것이 익스프레스(Express)이다. express 모듈을 사용하면 간단한 코드로 웹 서버의 기능을 구현할 수 있다. 특히 익스프레스에서 제공하는 미들웨어, 라우터를 사용하면 각각의 기능을 훨씬 편리하게 구성할 수 있다.

익스프레스 웹 서버 시작하기

익스프레스를 위한 프로젝트 폴더를 하나 만든다. 새로운 프로젝트 폴더를 만들었으니 package.json 파일을 다시 만들어야 한다. cmd에서 프로젝트 폴더로 이동한 후 npm init -y 명령어를 입력한다.

이제 익스프레스의 시작점이 되는 app.js 파일을 만든다.

var express = require('express'), http = require('http');
//익스프레스 객체 생성
var app = express();
//기본 포트를 app 객체에 속성으로 설정
app.set('port', process.env.PORT || 3000);
//Express 서버 시작
http.createServer(app).listen(app.get('port'), function(){
    console.log('익스프레스 서버 시작');
});
cs

우선 이 파일을 실행하기 위해서는 express 모듈을 설치해야 한다. cmd에 프로젝트 폴더에서 npm install express --save 를 입력하자. --save 옵션은 package.json에 모듈을 설치한 내용을 바로 반영해준다.

Express, http 모듈을 불러오고 express() 함수를 호출하여 반환된 객체를 app 변수에 지정 후 app.set()을 통해 app 객체에 정의된 함수를 호출한다. 그 다음 createServer() 메소드를 호출할 때 파라미터로 app 변수를 전달한다.

여기서 app 객체는 express() 메소드 호출로 만들어지는 익스프레스 서버 객체이다. 이 익스프레스 서버 객체가 가진 주요 메소드는 다음과 같다.

set(name, value): 서버 설정을 위한 속성 지정
get(name): 서버 설정을 위해 지정한 속성 꺼내오기
use([path,] function [,function]): 미들웨어 함수 사용
get([path,] function): 특정 패스로 요청된 정보 처리

set() 메소드는 웹 서버의 환경을 설정하는 데 필요한 메소드이다. title 속성을 app 객체에 넣어두었다가 필요할 때 꺼내어 사용하고 싶다면 app.set('title', 'My App')처럼 set() 메소드를 호출하여 넣어둘 수 있다. 그러나 설정한 속성의 이름이 미리 정해진 이름이라면 웹 서버 설정에 영향을 미친다. 서버 설정을 위해 미리 정해진 주요 속성의 이름은 다음과 같다.

env: 서버 모드 설정
views: 뷰들이 들어있는 폴더/폴더 배열 설정
view engine: 디폴트로 사용할 뷰 엔진 설정 (보통 ejs, pug 사용)

위 코드에서 사용한 app.set()은 port 속성을 설정한다. process.env 객체에 PORT 속성이 있으면 그 속성을 사용하고, 없으면 3000번 포트를 사용한다. 이렇게 설정한 포트 번호는 마지막 listen() 메소드를 호출할 때 app.get('port')와 같은 코드를 사용하여 포트 속성을 꺼내온 후 파라미터로 전달된다.

웹 브라우저에서 localhost:3000으로 접속하면 아무런 응답이 없을 것이다. 아직 어떤 응답을 할 것인지 지정하지 않았기 때문이다.

미들웨어로 클라이언트에 응답 보내기

이제 use() 메소드를 사용하여 미들웨어를 설정하는 방법을 알아보자. 노드에서는 미들웨어를 사용하여 필요한 기능을 순차적으로 실행할 수 있다. 익스프레스에서는 웹 요청과 응답에 관한 정보를 사용해 필요한 처리를 진행할 수 있도록 독립된 함수로 분리하는데, 이렇게 분리된 각각의 것들을 미들웨어라고 한다. 각각의 미들웨어는 next() 메소드를 호출하여 그다음 미들웨어가 처리할 수 있도록 순서를 넘길 수 있다.

라우터는 클라이언트의 요청 패스를 보고 이 요청 정보를 처리할 수 있는 곳으로 기능을 전달해주는 역할을 한다. 이 역할을 라우팅(Routing)이라고 하는데, 클라이언트의 요청 패스에 따라 각각을 담당하는 함수로 분리시키는 것이다. 응답 처리를 하는 함수를 별도로 분리해서 만든 다음 get() 메소드를 호출하여 라우터로 등록할 수 있다.

이제 미들웨어를 넣어서 웹 서버를 만들어보자.

var express = require('express'), http = require('http');
var app = express();
app.use(function(req, res, next){
    console.log('첫 번째 미들웨어에서 요청 처리');
    res.writeHead('200', {'Content-Type':'text/html;charset=utf8'});
    res.end('<h1>Express 서버에서 응답함</h1>');
});
http.createServer(app).listen(3000function(){
    console.log('Express 서버가 3000번 포트에서 시작');
})
cs

use() 메소드를 호출하여 미들웨어를 하나 등록했다. use() 메소드로 등록한 함수들은 등록 순서에 따라 클라이언트 요청을 처리한다. 여기에서는 하나의 미들웨어만 등록했으므로 하나만 호출되며, 이 미들웨어에서 클라이언트로 응답을 보낸다.

localhost:3000에서 접속하면 res 객체에 등록해놓은 메시지를 확인할 수 있다.

여러 개의 미들웨어 사용하기

여러 개의 미들웨어를 등록하여 여러가지 기능을 수행하고 싶다면 각각의 미들웨어 안에서마지막에 next() 메소드를 호출하여 다음 미들웨어로 처리 결과를 넘겨주어야 한다.

var express = require('express'), http = require('http');
var app = express();
app.use(function(req, res, next){
    console.log('첫 번째 미들웨어 요청 처리');
    
    req.user = 'zini';
    
    next();
});
app.use('/'function(req, res, next){
    console.log('두 번째 미들웨어 요청 처리');
    
    res.writeHead('200', {'Content-Type':'text/html;charset=utf8'});
    res.end('<h1>Express 서버에서 ' + req.user +'가 응답함</h1>');
});
http.createServer(app).listen(3000function(){
    console.log('Express 서버가 3000번 포트에서 시작');
})
cs

위 코드와 비교하면 여러 개의 미들웨어 사용도 간단한 것을 알 수 있다. 첫 번째 미들웨어에서 req 객체에 user 속성을 추가하고 문자열을 넣은 다음 next() 메소드로 두 번째 미들웨어로 넘긴다. 두 번째 미들웨어에서는 req 객체에 설정된 user 속성을 확인하여 출력해준다.

미들웨어 안에서는 기본적으로 요청 객체인 req와 응답 객체인 res 객체를 파라미터로 전달받아 사용할 수 있다. 그리고 이 미들웨어 함수를 호출한 app 객체도 참조할 수 있도록 req 객체의 속성에 app 객체가 들어가있다.

댓글 없음:

Powered by Blogger.