node의 HTTP 모듈과 Connect, Express 의 관계


발생일: 2013.03.09

문제:
작은 node 앱에 Express 를 사용하고 있다.
기본 HTTP 모듈과 Express 의 역할에 대해선 잘 알겠는데,
Connect 에 대해선 명확히 감이 잡히지 않는다.

Connect 는 정확히 뭐고, 세 모듈의 관계는 어떻게 될까?


해결책:

간략한 결론 먼저.
노드는 기본적으로 HTTP 모듈을 가지고 있고,
Connect 는 HTTP 모듈에 여러 플러그인(정적 파일, 로깅, 캐싱, 압축 등)을 추가할 수 있는 미들웨어 프레임워크다.
Express 는 Connect 를 내장하고 있는 웹 애플리케이션 프레임워크다.


좀더 자세히,
Connect 위주로 찬찬히 살펴보면, 다음과 같다.


node.js 에서는 기본적으로 HTTP 모듈을 내장하고 있고,
아래와 같이 createServer() 메서드로 간단하게 HTTP 서버를 구동할 수 있다.

  var http = require('http');
  http.createServer(function (req, res) {
    res.writeHead(200, {
      'Content-Type': 'text/plain'
    });
    res.end('Hello World');
  }).listen(3000);


실제로 서비스를 제공할 목적이라면,
여기에 쿠키 핸들링이나 세션 처리, 라우팅, 스태틱 파일 처리 등 추가 기능이 필요하다.

노드의 HTTP 모듈은 로우 레벨의 API를 제공하기 때문에,
나머지 기능은 직접 구현해야 한다.

Connect 는 이런 기능들을 쉽게 붙이고 확장할 수 있게 설계한 모듈이고,
다양한 종류의 플러그인을 기본적으로 제공한다.
노드의 HTTP 모듈을 래핑하고 있기 때문에, HTTP 모듈 없이 아래와 같이 호출할 수 있다.

  var connect = require('connect');
  var app = connect()
      .use(connect.logger('dev'))
      .use(connect.static('public'))
      .use(function (req, res) {
        res.end('Hello World');
      })
      .listen(3000);


`use()` 메서드에 파라미터로 전달하고 있는 것이 플러그인(미들웨어)이다.

위 샘플은 버전 2.x 대의 코드인데,
검색해서 나오는 튜토리얼 중에는 버전 1.x 대의 방식을 사용하는 게 많더라.
이전 버전에서는 Connect 객체의 `createServer()` 메서드를 호출하고,
파라미터로 플러그인을 넘기고 있다.

  var Connect = require('connect');
  Connect.createServer(
    Connect.logger(),
    Connect.gzip(),
    Connect.session()
  );


코드를 보니 하위 호환성을 보장하고 있어서 위 방법으로 호출해도 문제는 없겠으나,
이왕이면 2.x 대 방식으로 호출하는 게 좋겠다.


여튼, connect 는 `use()` 메서드로 받은 플러그인을,
요청 전과 응답 전에 추가된 순서대로 호출한다.
각 플러그인은, 요청 객체와 응답 객체를 받아 추가 기능을 구현할 수 있다.

플러그인은, 요청 객체, 응답 객체, 다음 플러그인을 호출하는 함수를 파라미터로 갖는 함수이다.
이 규칙만 지키면 간단히 플러그인을 추가할 수 있다.
예를 들어, 요청 전/후에 간단한 콘솔을 출력하는 플러그인을 아래와 같이 구현할 수 있다.

  [consolelogger.js]
  module.exports = function (req, res, next) {
    console.log('before request: ', req.url); // 요청 전에 호출
    next(); // 다음 플러그인을 호출한다.
    console.log('before response: ', req.url); // 응답 전에 호출
  };

  [main.js]
  var connect = require('connect'),
    consolelogger = require('./consolelogger');
  var app = connect()
      .use(consolelogger)
      .use(function (req, res) {
        res.end('Hello World');
      })
      .listen(3000);


자바 개발자라면, 서블릿 필터를 떠올리면 된다.
서블릿 필터와 거의 동일하게 동작하고, 필터에서의 `doFilter()` `next()`라 생각하면 된다.


Connect 에서 제공하고 있는 플러그인도 위와 같은 방식으로 구현되어 있으며,
20여개 이상의 기본 플러그인을 제공하고 있다.


Express 는 Connect 를 내장하고 있는 웹 프레임워크이다.
HTTP 메서드 처리, 라우팅 등을 쉽게 처리할 수 있고,
Connect 와 비슷한 방식으로 미들웨어를 제공하고, 직접 추가할 수도 있다.


난 사용해보진 않았지만,
Connect 와 Express 모두 루비의 웹 프레임워크에서 영감을 받았다 하고,
Connect 는 Rack, Express 는 Sinatra 와 비슷하다 한다.



참고:
- Just Connect it Already: http://howtonode.org/connect-it




카테고리

분류 전체보기 (702)
About me. (6)
Daylogs (667)
비공개 (0)
영어공부 (0)
My works - 추억 (29)