ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 미들웨어란?
    서버/Node.js 2017. 12. 1. 00:26

     

     

    프로젝트를 진행하면서 느낀 것은 내가 아직 많이 개념이 모자라다는 것이었다. 대충 어느정도 흐름이 잡혔다 싶었다가도 한 번 막히면 다시 원상태로 돌아오는 것이 내 스스로에게 너무나도 답답하게 느껴졌다. 천천히, 하지만 정확히. 그것은 어디에나 통하는 '정(正)도'라고 생각한다. 그래서 다시 책 속에 나와있는 개념들을 하나하나 정리해볼까 한다. 


    그리고 한동안 프로젝트의 진행 내용에 대해서 꾸준히 포스팅하고 싶었지만, 뭔가를 어서 만들어 성취감을 느끼고 싶다는 마음이 너무나도 크게 들어서 그러지를 못한 거 같다. 어차피 지금 만드는 프로젝트는 정말로 내가 초보 딱지를 떼기 위해서 만드는 것이기 때문에, 이 프로젝트가 완성되면, 차후 다른 프로젝트를 진행하면서 차근차근 포스팅하도록 하겠다.


    다시 본론으로 돌아와서, Node.js의 핵심 개념 중 하나인 미들웨어(Middleware)에 대해서 알아보도록 하자.


    1. 미들웨어


    나는 app.use라는 문법을 통해 미들웨어의 개념을 대강 익혔다. 하지만 정확히 그 쓰임새가 무엇이고, 어떻게 돌아가는 지는 완전히 이해하지를 못한 상태였다. 나같은 경우, 하나가 이해 안되면 매우 답답함을 느끼는 게 있어서 이 기회에 잘 알아보려고 한다.


    책에서는 미들웨어에 대해 다음과 같이 설명한다. 


    "미들웨어란 기능, 특히 어플리케이션에 대한 

    HTTP 요청에서 동작하는 기능을 캡슐화하는 방법을 의미한다"


    캡슐화는 자바 혹은 자바스크립트를 배우면서 익혔던 개념으로, 기능을 한 곳에 모아서 캡슐 안에 보관하고, 캡슐을 덮는 것처럼 외부에서 보이지 않도록 감추는 것을 의미한다. 아... 아직은 잘 이해가 가질 않는다. 그렇다면 미들웨어에 대한 이해를 높이기 위해 구성요소를 살펴보자.


    "미들웨어는 단순히 매개변수 세 가지를 받는 함수이다. 

    세 가지 매개변수란 요청 객체와 응답 객체, 그리고 'next' 함수이다."


    아하! 쉽게 기억하자면 세 가지 매개변수를 받는데, 두 가지 매개변수는 HTTP 요청과 관련있는 변수이고, 미들웨어는 이에 대해 처리를 하는 놈이다. 대충 이해가 간다.  다른 사이트에서 미들웨어에 대해서 찾아보면 파이프라인이라는 용어가 자주 등장한다. 파이프라인과 미들웨어의 관계에 대해 설명하자면 다음과 같다. 미들웨어는 파이프라인이라 부르는 것 속에서 실행된다. 물이 흐르고 있는 파이프에서는 게이지와 밸브가 존재하며, 여기서 가장 중요한 것은 순서이다. 순서에 따라 파이프 속에 있는 물질이 달라질 것이다. 


    파이프라인이라는 개념을 통해서 미들웨어를 배치할 때 순서가 중요하다는 걸 알 수 있었다. 이외에도 꼭 기억해야할 사항은 다음과 같다.


    - 익스프레스 앱에서는 app.use를 호출해 미들웨어를 삽입한다. 익스프레스 4.0에서는 미들웨어와 라우트 핸들러가 연결한 순서대로 호출되므로 순서를 훨씬 명확히 알 수 있다. 그리고 이러한 파이프라인 맨 마지막 미들웨어로는 보통 에러를 처리하는 폴백 핸들러를 두는 것이 좋다.


    - 파이프라인에서 각 미들웨어에 전달된 next 함수가 하는 일은 요청의 전달이다. next( )를 호출하지 않으면 해당 요청은 그 미들웨어에서 종료된다.


    여기까지 미들웨어의 중요한 개념에 대해 알아보았다. 밑의 문제를 풀어보면서 배운 내용을 확실히 내 것으로 만들도록 하자. 


    밑에 적힌 코드가 실행될 때 과연 콘솔과 페이지 화면에는 어떻게 출력될까?? 


    var app = require('express')();

    app.use(function(req, res, next){
        console.log('\n\nCATANP');
        next();
    });

    app.get('/a', function(req, res){
        console.log('/a: route terminated');
        res.send('a');
    });
    app.get('/a', function(req, res){
        console.log('/a: never called');
    });
    app.get('/b', function(req, res, next){
        console.log('/b: route not terminated');
        next();
    });
    app.use(function(req, res, next){
        console.log('JO');
        next();
    });
    app.get('/b', function(req, res, next){
        console.log('/b (part 2): error thrown' );
        throw new Error('b failed');
    });
    app.use('/b', function(err, req, res, next){
        console.log('/b error detected and passed on');
        next(err);
    });
    app.get('/c', function(err, req){
        console.log('/c: error thrown');
        throw new Error('c failed');
    });
    app.use('/c', function(err, req, res, next){
        console.log('/c: error deteccted but not passed on');
        next();
    });

    app.use(function(err, req, res, next){
        console.log('unhandled error detected: ' + err.message);
        res.send('500 - server error');
    });

    app.use(function(req, res){
        console.log('route not handled');
        res.send('404 - not found');
    });

    app.listen(3000, function(){
        console.log('listening on 3000');
    });


    위의 js 파일을 실행시키고, URL에 다음과 같이 입력하여 결과를 확인하자.


    localhost:3000
    localhost:3000/a
    localhost:3000/b
    localhost:3000/c




     

     

    '서버 > Node.js' 카테고리의 다른 글

    표준입출력  (0) 2020.02.06
    정보의 전달(GET, POST)  (0) 2017.11.27
    MongoDB와 Node.js  (0) 2017.11.25
    MVC 흐름  (0) 2017.11.25
    [Pug(구 Jade)] Error - Cannot read property 'length' of undefined  (0) 2017.11.25

    댓글

Designed by Tistory.