- express middleware란
- next를 이용한 middleware chaining
처음 middleware라는 개념을 접했을 땐 django framework의 decorator처럼 요청에 대한 처리를 하는 모든 view들이 공통적으로 처리해야 하는 기능(예를 들면 token 판단)을 일괄적용하기 위한 목적이 주인 것으로 생각했다. 하지만 expressjs.com에서는 middleware를 다음과 같이 정의한다.
middleware 함수는 요청 오브젝트(req), 응답 오브젝트 (res), 그리고 애플리케이션의 요청-응답 주기 중 그 다음의 미들웨어 함수 대한 액세스 권한을 갖는 함수입니다. 그 다음의 미들웨어 함수는 일반적으로 next라는 이름의 변수로 표시됩니다.
미들웨어 함수는 다음과 같은 태스크를 수행할 수 있습니다.
- 모든 코드를 실행.
- 요청 및 응답 오브젝트에 대한 변경을 실행.
- 요청-응답 주기를 종료.
- 스택 내의 그 다음 미들웨어 함수를 호출.
즉 대부분의 비즈니스 로직처리를 middleware로 할 수 있으며 Express란 결국 일련의 middleware 함수의 호출이다. 여기서 '일련의' 라는 용어를 주목해야 한다.
필요하면 여러 middleware를 stack에 쌓듯이 순서대로 chaning을 할 수 있다. 마치 함수가 다른 함수를 호출하는 것처럼...
그럼 어떻게 middleware를 만들고 하나의 request에 대해 middleware chaining을 호출하는지 알아보자.
middleware chaining과정에서 보통 그 다음 middleware 함수는 'next' 란 이름의 변수로 표시된다.
express에는 use(), METHOD()가 있는데 이를 이용해 express 객체에 middleware를 연결할 수 있다. 아래 코드를 보자.const http = require('http') const express = require('express') const app = express() app.use(function(req, res, next) => { console.log('모든 요청에 대해 출력하는 log') next() })
위에서 'app' 이라는 express 객체를 만들어 use() 를 호출한다. 이는 모든 http request에 대해 callback함수가 먼저 선호출되며 next()를 통해 그 다음 middleware에게 제어권을 넘긴다는 내용의 code 이다.
만약 전체 request가 아니라 특정 path에만 적용하고 싶으면 use() 호출시 callback 앞에 path를 넣어주면 된다. 아래처럼 말이다.app.use('/user', function(req, res, next) => { console.log('user관련 요청에 대해 출력하는 log') next()} )
이러면 '/user' path에 해당하는 request들에게만 middleware가 연결된다.
만약에 2개 이상의 middleware를 chaning 하고 싶다면 어떻게 할까? use 함수호출시 callback을 여러개 넣으면 된다.
app.use('/user', function(req, res, next) => { console.log('user관련 요청에 대해 출력하는 log') next()}, function(req, res, next) => { console.log('user관련 요청에 대해 2번제 출력하는 log') next()} )
이렇듯 next를 통해 chaining을 할 수 있다.
그런데 우리는 이미 'TIL #1. Node에 대한 이해와 맛보기' 를 통해 express의 RESTful 함수(get, post...)등을 사용하여 request를 분기 처리해봤었다. 위에서 app.METHOD() 로도 middleware를 연결할 수 있다 하였으니 해보자.
만약에 2개 이상의 middleware를 chaning 하고 싶다면 어떻게 할까? use 함수호출시 callback을 여러개 넣으면 된다.
app.get('/user/:id', function(req, res, next) => { console.log('user관련 요청에 대해 선출력하는 log') next()}, function(req, res, next) => { res.send("응답입니다") } )
GET method로 특정 user정보를 요청하는 request에 대해 위처럼 middleware를 연결할 수 있다.