클라이언트 요청을 위한 URL 스키마를 라우트(Route) 라고 하며, 서버에서는 라우팅 작업을 통해 클라이언트와 통신 인터페이스를 제공해 준다. 라우터는 미들웨어 중 하나에 속하며, 클라이언트의 요청 경로에 따라서 처리를 분기시켜 준다는 특징이 있다. (클라이언트의 요청과 처리 메소드를 매핑 시키는 역할을 한다, Spring의 컨트롤러 같은 역할이라고 볼 수 있다)


라우팅 기초

기본적인 라우팅 설정 코드는 아래와 같다.

// 빌트인(내장) 모듈 불러오기
var express = require('express');
var http = require('http');
 
// 익스프레스 객체 및 웹 서버 객체 생성
var app = express();
var server = http.createServer(app);
 
// 포트 설정 및 요청 대기
var port = 3333;
server.listen(port);
 
// 라우팅
app.use('/users', function(req, res){
    res.send('test page');
});

익스프레스 객체의 use 메소드는 미들웨어를 등록할 때 사용하는 메소드이다.

그렇다. 라우팅 역시 미들웨어 중 한 종류라고 바로 위에서 설명했었다. 미들웨어는 클라이언트의 모든 요청에 대해 적용되는 처리(함수)의 집합이며, 라우팅은 요청 경로에 따라서 다르게 적용되는 처리(함수)의 집합이다.

라우팅 설정은 미들웨어 설정과 동일하지만 콜백 메소드를 선언하기 전에, 라우팅과 매핑시킬 클라이언트 요청 경로를 입력하면 된다. (위 코드의 경우 도메인/users 로 요청이 가면 해당 라우팅의 내용이 실행된다)


HTTP Method

위의 app.use 는 한 경로에 대한 모든 요청에 대해 같은 처리를 진행하지만, HTTP Method에 따라서 다른 분기를 하고 싶은 경우가 있을 것이다. 그럴땐 익스프레스 객체에 있는 get, post, put, delete, … 등의 HTTP Method 함수를 사용하면 된다. 기본적인 라우팅 설정 코드는 아래와 같다.

// 빌트인(내장) 모듈 불러오기 
// 익스프레스 객체 및 웹 서버 객체 생성 
// 포트 설정 및 요청 대기
...
 
// 라우팅(GET)
app.get('/users', function(req, res){
    res.send('HTTP Method : GET');
});
 
// 라우팅(POST)
app.post('/users', function(req, res){
    res.send('HTTP Method : POST');
});

익스프레스 서버 객체인 app 은 HTTP Method 명과 동일한 이름의 함수를 가지고 있다. 이는 같은 경로로 접근해도 HTTP Method 에 따라서 다른 처리를 할 수 있게 해준다. (RESTful API…)

  • app.post()
  • app.get()
  • app.put()
  • app.delete()

라우팅에서 파라미터 접근(GET)

클라이언트의 요청 정보는 경로 이외에도 파라미터, 헤더 등의 형태로 전달 되는 경우도 있다. 그 중에 GET 방식에서 URL 파라미터로 요청 정보를 전달하는 경우, 이 값을 얻는 방법에 대해 알아보자.

// 빌트인(내장) 모듈 불러오기
// 익스프레스 객체 및 웹 서버 객체 생성
// 포트 설정 및 요청 대기
...
 
// 라우팅
app.get('/users', function(req, res){
    res.send({name:req.query.name, memCnt:req.query.memCnt});
    //res.send({name:req.query['name'], memCnt:req.query['memCnt']});
});

“req.query.파라미터” 또는 “req.query[‘파라미터’]” 를 통해 파싱된 파라미터에 접근할 수 있다.(8행)


라우팅에서 파라미터 접근(POST)

// 빌트인(내장) 모듈 불러오기
var express = require('express');
var http = require('http');
var bodyParser = require('body-parser'); // POST 파라미터 파싱 모듈
 
// 익스프레스 객체 및 웹 서버 객체 생성
var app = express();
var server = http.createServer(app);
 
// body-parser 모듈을 미들웨어로 설정
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended:true}));
 
// 포트 설정 및 요청 대기
var port = 3333;
server.listen(port);
 
// 라우팅
app.get('/users', function(req, res){
    res.send({name:req.body.name, memCnt:req.body.memCnt});
    //res.send({name:req.body['name'], memCnt:req.body['memCnt']})
});

Express 4.x 버전까지는 GET, POST 방식 상관 없이 모두 req.param 의 속성을 통해 접근할 수 있었지만, 혼란을 야기할 수 있다고 생각하여 Express 5.x 버전부터는 삭제되었다.

이후 POST(또는 PUT) 방식에 대한 파라미터를 얻기 위해서는 빌트인(내장) 모듈인 “body-parser” 를 미들웨어에 등록해서 사용해야 한다. “body-parser” 모듈을 불러오고(4행), 해당 모듈의 API를 미들웨어에 등록(11~12행)하는 것으로 파라미터를 파싱할 준비를 마칠 수 있다.

“req.body.파라미터” 나 “req.body[‘파라미터’]” 를 통해 파싱된 파라미터에 접근할 수 있다.(20행)


어플리케이션 레벨 미들웨어 vs. 라우터 레벨 미들웨어 (라우팅 모듈화)

어플리케이션 레벨 미들웨어는 익스프레스 객체 자체에 적용되는 미들웨어이다. 우리가 지금까지 사용해 온 app.use() 를 통한 모든 미들웨어는 어플리케이션 레벨 미들웨어이다.

또한 app.get(), app.post(), … 등의 익스프레스 객체의 메소드를 활용한 라우팅 역시 어플리케이션 레벨 라우팅이 된다.

이는 즉, 하나의 익스프레스 객체, 곧 모든 서버에 동일하게 적용되는 설정이라는 뜻이다.

// 빌트인(내장) 모듈 불러오기 
// 익스프레스 객체 및 웹 서버 객체 생성 
// 포트 설정 및 요청 대기
...
 
// 어플리케이션 레벨 라우팅(모든 서버에 동일하게 적용)
app.use('/users', function(req, res){
    res.send('users test page');
});

그러나, 이러한 통일된 시스템을 바라지 않을 때도 있는 법이다. 그래서 익스프레스 객체에서 라우팅 객체를 따로 생성할 수 있게 했으며, 해당 라우팅 객체에 라우팅 설정을 하는 것으로 라우팅을 모듈화 하는 방법이 있다.

var express = require('express');
var router = express.Router();
 
// 라우팅 레벨 미들웨어 
router.use(function timeLog(req, res, next) {
    console.log('클라이언트 요청 확인')
    console.log('시간: ', Date.now());
    next();
});
 
// 라우팅 모듈화 
router.get('/', function(req, res) {
      res.send('홈페이지 입니다.');
});
 
router.get('/about', function(req, res) {
      res.send('정보페이지 입니다.');
});
 
module.exports = router;

익스프레스 객체는 Router() 라는 메소드를 통해 라우팅 객체를 별도로 생성할 수 있다. 익스프레스 객체 자신이 아닌, 해당 라우팅 객체에 미들웨어 및 라우팅을 등록하고, 이 객체를 모듈화 시킨다면, 라우팅 자체가 모듈이 로딩되었을 때만 실행되는, 라우팅 모듈화가 가능하다.

// 빌트인(내장) 모듈 불러오기 
// 익스프레스 객체 및 웹 서버 객체 생성 
// 포트 설정 및 요청 대기
...
 
// 위 코드에서 생성한 라우터 모듈 불러오기
var router = require('./router');
 
// 익스프레스 객체에 라우터 모듈을 미들웨어로 등록
app.use('/', router);

서버 코드에서는 라우팅 모듈을 불러오기만 하는 것으로, 라우팅 설정이 가능하므로, 코드 가독성 및 분할에도 도움이 된다.


route() 메소드

app 과 router 레벨 모두에서 동일하게 사용될 수 있는 route() 라는 메소드가 존재한다. 이 메소드는 기존 HTTP Method 들과 동일한 기능을 하지만, 자기 자신을 반환하기 때문에 체인이 가능하기에, 다양한 HTTP Method 에 대한 라우팅을 작성할 때 코드의 중복성과 오타를 줄이는 이점이 있다. 또한, 모든 HTTP 요청에 대해 동일한 처리를 실행하는 all 메소드도 지원하기 때문에 여러모로 편리하다는 강점을 가지고 있다. (해당 기능은 Express 4.x 버전부터 지원한다)

var express = require('express');
var router = express.Router();
 
// 체인 시스템 
router.route('/notice')
    .get(function(req, res){ ... })
    .post(function(req, res){ ... })
    .put(function(req, res){ ... })
    .delete(function(rqe, res){ ... });
 
// all() 메소드
router.route('/info').all(function(req, res){
    ...
});
 
module.exports = router;