ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Express] 프레임워크 미들웨어(Middleware)란?
    개발/node.js 2020. 3. 24. 22:12

    미들웨어란, 애플리케이션의 요청-응답 주기 중 그 다음의 미들웨어 함수에 대한 액세스 권한을 갖는 함수입니다. 그 다음의 미들웨어 함수는 일반적으로 next라는 이름의 변수로 표시됩니다.

    자 뭔소리인고 하니,

    1. express 프레임워크 === 웹 프레임워크 이다.

    결국 TCP/IP를 기반으로 HTTP 패킷을 생성, 해석을 해주는 프레임워크라는 것이다.

    HTTP Body부에 존재하는 가장 중요한 멤버들은 request, response 이다.

    클라이언트가 보내는 request를 받고 response를 생성해서 보내주는 과정의 중간(Middle)에 개발자가 간섭하여 로직생성, request || response 변경, 흐름제어 등을 한다는 것이다.

    공식문서(https://expressjs.com/ko/guide/using-middleware.html)에는 다음과같이 말하고 있다.

    미들웨어 함수는 다음과 같은 태스크를 수행할 수 있습니다.
    1. 모든 코드를 실행.
    2. 요청 및 응답 오브젝트에 대한 변경을 실행.
    3. 요청-응답 주기를 종료.
    4. 스택 내의 그 다음 미들웨어 함수를 호출.

    해석

    1. 모든 코드를 실행.

    - 미들웨어 함수에 적은 코드를 실행한다. (당연)

     

    2. 요청 및 응답 오브젝트에 대한 변경을 실행.

    - HTTP통신은 request를 받고 response를 보내는 것이니, 해당 오브젝트를 개발자의 입맛에 맞게 변경할 수 있다는 것

     

    3. 요청-응답 주기를 종료.

    - 요청-응답의 흐름을 제어할 수 있다는 것이다.

    if( request.method === 'POST' ){
        return;
    }else{
        next();
    }

    위의 예는 post 메소드로 요청이 들어오면 응답하지 않고 종료하고, 나머지 메소드는 응답한다는 뜻이다. next는 4번에서 다룰 것임

    4. 스택 내의 그 다음 미들웨어 함수를 호출.

    var app = express();

    로 생성된 Application 오브젝트에는 use() 라는 함수가 존재한다.

    use() 함수를 이용하여 미들웨어를 등록, 순서대로 실행이 된다.

    그런데 여기서 말하는 스택이란 자료구조 스택이 아니라 미들웨어들을 뜻하는 것 같다.(추측...)

    먼저 등록한 미들웨어 순서대로 실행이 된다고 하면 First-In-First-Out 인 자료구조 를 이용할 것 같은데 말이다...

    아니면 미들웨어함수들을 등록된 역순으로 스택구조로 재생성 하는 것일지도 모르겠다. 

    ( 잘못된 해석이라면 댓글을 달아주시면 감사하겠습니다. )

     

    여기서 사용되는 변수가 next 변수이다.

    예를들어

    위와 같은 코드는 4개의 미들웨어함수를 등록한 것이다.

    1. logger('dev')

    2. express.join()

    3. express.urlencoded({extended: false})

    4. cookieParser()

    등록된 순서와 실행 순서는 동일하다.

    이때 내부적으로 각 미들웨어 함수는 next라는 매개변수를 받아서 자신의 함수 실행이 끝나게 되면 next()로 다음등록된 미들웨어 함수를 호출하여 순서대로 실행되는 것이다.

     

    이렇듯, 요청 -> 미들웨어함수 실행 -> 응답 순으로 express 프레임워크는 동작을 하게된다.

     

    자 그럼 실제코드로 동작여부를 확인해 보겠다.

    2개만 등록했다고 가정하고

    우리가 request 객체 header의 cookie들을 모아서 편하게 사용하기 쉽게 생성해주는 미들웨어를 알아볼 것이다.

    후에 next() 함수를 이용하여 view를 반환하는 미들웨어로 제대로 넘어가는지 확인까지 해볼 것이다.

     

    미들웨어 실행여부 알아보기

    1. http://localhost:3000 웹서버로 요청

    2. 등록된 미들웨어 순서대로 실행

        2.1 cookieParser() 미들웨어 실행

        내부를 살짝 파헤쳐보자

    function cookieParser (secret, options) {
      var secrets = !secret || Array.isArray(secret)
        ? (secret || [])
        : [secret]
    
      return function cookieParser (req, res, next) {
        if (req.cookies) {
          return next()
        }
    
        var cookies = req.headers.cookie
    
        req.secret = secrets[0]
        req.cookies = Object.create(null)
        req.signedCookies = Object.create(null)
    
        // no cookies
        if (!cookies) {
          return next()
        }
    
        req.cookies = cookie.parse(cookies, options)
    
        // parse signed cookies
        if (secrets.length !== 0) {
          req.signedCookies = signedCookies(req.cookies, secrets)
          req.signedCookies = JSONCookies(req.signedCookies)
        }
    
        // parse JSON cookies
        req.cookies = JSONCookies(req.cookies)
    
        next()
      }

    주의해서 봐야할 점은

    req.headers.cookie 로 접근하여 JSON 형태로 req.cookies 로 재생성 해준다는 것이다.

    2.2 next() 명령어로 indexRouter() 미들웨어함수 실행

    var indexRouter = require('./routes/index');

    var express = require('express');
    var router = express.Router();
    
    /* GET home page. */
    router.get('/', function(req, res, next) {
      console.log(req.cookies);
      res.render('index');
    });
    
    module.exports = router;
    

    위와같은 형태로 req.cookies로 접근해보면 해당 오브젝트의 모습을 console창으로 볼 수 있다.

     

    localhost:3000 으로 요청 후 발생되는 log

    1. undefined

        - cookieParser() 미들웨어 req.headers.cookie

    2. > Object {}

        - cookieParser() 미들웨어에서 Object 생성 후 req.cookies에 대입, indexRouter() 미들웨어 내부 req.cookies

    3,4,5. undefined

        - 정적 리소스 png, js, css 3개

        말인 즉슨 cookieParser() 미들웨어가 요청이 들어오면 항상 동작된다.

        Application.use() 공식문서(https://expressjs.com/ko/api.html#app.use)를 확인해보면 

    path parameter 생략 시 '/'(root path) 가 default

    path에 맞는 요청이 들어올 시 등록된 callback(미들웨어 함수)가 동작된다고 한다.

    지금은 path를 생략했기 때문에 root path로 인식하여 모든 요청에 대해 cookieParser() 미들웨어함수가 동작하는것이다.

    여기서 궁금증, app.use() 매개변수 path 값은 어떠한 값일까? 이는 "app.use()에 대해서" 라는 다음 포스트에서 다루도록 하겠다.

     

    ※요약

    express 미들웨어란?

    - 지정된 path에 대한 요청 - 응답 사이에 함수를 실행시키는 것

     

    PS. 동일한 path일 경우 공통적으로 발생할 로직을 직접 작성할 수도 있겠다. 

     

    댓글

Designed by Tistory.