본문 바로가기

공부/Node.js

[Node.js] express로 웹 서버 만들기(use() 미들웨어)

일단 express로 웹서버를 만들고 미들웨어와 라우터의 개념을 확실하게 다지고 갈 생각이다.

 

간단한 서버를 구축

var express = require('express')
    , http = require('http');


var app = express();

app.set('port', process.env.PORT || 3000); // set을 이용해서 속성을 저장해두고


http.createServer(app).listen(app.get('port'), function(){ 
    console.log('익스프레스 서버를 시작했습니다 : ' + app.get('port'));
});
//createServer에 app(express모듈)을 사용하여 서버를 구동하겠다는 명시를 해줌
//port속성을 get을 이용해서 사용한 상황

 

일단 별거없긴 하지만 간단하게 코드를 만들어 보았다. 말 그대로 서버의 역할만 하는 코드이다.

 

가장 윗줄에서 express모듈을 부를 때는 http도 꼭 같이 불러줘야한다. 그 이유는 express 모듈은 http를 기반으로 만들어졌기 때문이다. 그 밑에서 app라는 변수에 express를 담는다.

 

app.set은 app객체에 속성을 하나 주는 것 이다. 코드에는 port라는 속성에 process.env에 PORT가 있다면 PORT로 아니라면 3000으로 속성에 값을 부여한다.

 

밑의 createServer에서 listen을 통해서 연동을 하고 app.get을 사용하여 app객체의 속성을 가지고 온다.

구조를 보아 listen(포트번호, callback함수)의 구조인거 같다. 그럼 서버가 실행이 된다.

 

그래서 localhost:3000으로 들어가보니

 

아직 아무것도 없는 썰렁한 상태이다. 이유는 당연하게 요청이 왔을시에 어떤 식으로 줄 것인지 정하지 않았기 때문이다.

 

미들웨어를 이용하여 응답 보내기

 

위의 서버는 말그대로 서버가 존재만하고 크게 아무역할도 하지 않기 때문에 이번에는 응답을 보내는 것을 해보려고 한다.

 

미들웨어에 관해서 이해를 한 번 하고 가보자면 미들웨어와 라우터는 둘 다 '하나의 독립된 기능을 가진 함수'이다.

 

클라이언트 요청시 하나의 함수를 만들고 use를 통해서 미들웨어로 등록을 해놓으면 모든 요청은 이 미들웨어를 거치도록 할 수 있다고 한다. 말로만 들어선 역시나 이해가 안가니 코드를 찝어보면서 하나하나 리뷰해봐야겠다.

 

라우터는 이 클라이언트의 요청 경로를 보고 이 '요청 정보를 처리 할 수 있는 곳으로 기능을 전달'해주는 역할을 하는 녀석이다.

 

var express = require('express')
    , http = require('http')

var app = express();

app.set('port', process.env.PORT || 3000);

app.use(function(req, res, next){ //미들웨어의 역할을 하는 녀석
    console.log('첫번 째 미들웨어에서 요청을 처리함');
    
    res.writeHead('200', {'Content-Type' : 'text/html;charset=utf8'}); //헤더를 지정
    res.write('<h1>Express 서버에서 응답한 결과입니다.</h1>');
    res.end();
})

http.createServer(app).listen(app.get('port'), function(){ // 서버를 구동
    console.log('익스프레스 서버를 시작하였습니다 : ' + app.get('port'));
});

기본적인 코드의 구성은 위와 동일하나 app.use를 통해서 미들웨어를 하나 추가 시켜줬다. 여기서 app.use의 함수는 function(req, res, next) 모양의 callback 함수를 주어 미들웨어 진입시의 행동을 알려준다.

 

미들웨어는 여러개를 사용하는 것이 가능하다.

 

var express = require('express')
    , http = require('http')

var app = express();

app.set('port', process.env.PORT || 3000);

app.use(function(req, res, next){ //첫 번째 미들웨어
    console.log('첫번 째 미들웨어에서 요청을 처리함');
    
    req.user = 'mike';
    
    next(); //next를 통해서 다음 미들웨어로 넘겨줌
})

app.use('/', function(req, res, next){ //두 번째 미들웨어
    console.log('두번 째 미들웨어에서 요청을 처리함');
    
    res.writeHead('200', {'Content-Type' : 'text/html;charset=utf8'}); //헤더를 지정
    res.write('<h1>Express 서버에서 응답한 결과입니다.</h1>\n<h1>' + req.user + '</h1>');
    res.end();
})

http.createServer(app).listen(app.get('port'), function(){ // 서버를 구동
    console.log('익스프레스 서버를 시작하였습니다 : ' + app.get('port'));
});

이런 식으로 체인처럼 미들웨어를 연결시키게 된다. 여기서는 req.user에 mike를 저장하고 다음 미들웨어에서 req.user를 사용하여 앞에서 초기화 했던 내용을 그대로 사용할 수 있게 보여주었다.

 

여기서 두 가지 의문점이 있어서 해소하고 가기 위해 코드 두 가지를 사용해 보았다.

 

var express = require('express')
    , http = require('http')

var app = express();

app.set('port', process.env.PORT || 3000);

app.use(function(req, res, next){ //1
    console.log('첫번 째 미들웨어에서 요청을 처리함');
    
    req.user = 'mike'; //임의의 변수
    next();
})

app.use('/', function(req, res, next){ //2
    console.log('두번 째 미들웨어에서 요청을 처리함');
    req.test = 'test'; //임의의 변수2
    next();
})

app.use('/', function(req, res, next){ //3
    console.log('세번 째 미들웨어에서 요청을 처리함');
    
    res.writeHead('200', {'Content-Type' : 'text/html;charset=utf8'}); //헤더를 지정
    res.write('<h1>Express 서버에서 응답한 결과입니다.</h1>\n<h1>' + req.user + req.test + '</h1>');
    res.end();
})

http.createServer(app).listen(app.get('port'), function(){ // 서버를 구동
    console.log('익스프레스 서버를 시작하였습니다 : ' + app.get('port'));
});

일단 궁금점 하나는 req.~~~에서 이 ~~~에 해당하는 변수는 따로 만들어주지 않아도 넘기는게 가능한가?이다.

그래서 하나는 기존에 사용했던 user 그 다음 미들웨어에서는 test라는 임의의 변수를 이용하여 넘겨보기로 했다.

 

결론은 가능하다. 위의 mike와 test가 전달되었다는 것을 확인하였다.

 

다른 궁금점은 미들웨어의 동작 순서이다. 어떻게 첫 번째와 두 번째 그리고 세 번째인지 구분하는 문구가 하나도 없어서 혹시 작성 순서에 따라 이게 실행되는가?를 확인해보았다.

 

var express = require('express')
    , http = require('http')

var app = express();

app.set('port', process.env.PORT || 3000);

app.use(function(req, res, next){ //미들웨어의 역할을 하는 녀석
    console.log('첫 번째 미들웨어에서 요청을 처리함');
    
    req.user = 'mike';
    
    
    next();
})

app.use('/', function(req, res, next){ //미들웨어의 역할을 하는 녀석
    console.log('세 번째 미들웨어에서 요청을 처리함');
    
    res.writeHead('200', {'Content-Type' : 'text/html;charset=utf8'}); //헤더를 지정
    res.write('<h1>Express 서버에서 응답한 결과입니다.</h1>\n<h1>' + req.user + req.test + '</h1>');
    res.end();
})

app.use('/', function(req, res, next){ //미들웨어의 역할을 하는 녀석
    console.log('두 번째 미들웨어에서 요청을 처리함');
    req.test = 'test';
    next();
})

http.createServer(app).listen(app.get('port'), function(){ // 서버를 구동
    console.log('익스프레스 서버를 시작하였습니다 : ' + app.get('port'));
});

코드는 위의 코드와 동일하다 단지 세 번째 미들웨어와 두 번째 미들웨어의 순서를 바꾼 것 뿐이다. 이 코드의 실행결과를 보이면

 

결론은 순서대로 작동한다. 변수를 정의 하지않아 user.test = undefined로 되어 실행되는 것을 알 수 있다.