[node, express] middleware 미들웨어란?

김원진·2021년 11월 12일

[Node, Express]

목록 보기
1/2

"Middleware functions are functions that have access to the request object (req), the response object (res), and the next function in the application’s request-response cycle."

미들웨어 함수는 req(요청) 객체, res(응답) 객체, 그리고 어플리케이션 요청-응답 사이클 도중 그 다음의 미들웨어 함수에 대한 엑세스 권한을 갖는 함수다

간단히 얘기하자면 클라이언트에서 요청이 오고 그 요청을 보내기 위해 응답하려는 중간(미들)에 목적에 맞게 처리를 하는, 말하자면 거처가는 함수라 보면 될것 같다

예를 들어서 요청-응답 도중에 시간을 콘솔 창에 남기고 싶다고 가정해 보자

미들웨서 함수를 도중에 넣어 표시한 뒤 계속해서 다음 미들웨어를 처리할 수 있도록 하는 것이다

다음 미들웨어 함수에 대한 엑세스는 next함수를 이용해서 다음 미들웨어로 현재 요청을 넘길 수 있다

하나의 예시를 보자

app.use 안에 있는 모든 함수들은 모두 미들웨어이며 요청이 올때마다 이 미들웨어를 거치며 클라이언트에게 응답하게 된다

이 미들워어의 사용의 편이점은 페이지를 랜더링 할때 사용자 인증을 앞서 거친 후에 랜더링하고 싶을 때 사용자 인증 미들웨어를 작성하고 앞에 삽입하게 되면 편리하다

마들웨어의 특징을 간략히 정리하면 다음과 같다

  1. 모든 코드를 실행
  2. 다음 미들웨어 호출(미들웨어가 순차적으로 실행)
  3. res, req 객체 변경 가능
  4. 요청-응답 주기를 종료(response methods를 사용)
var express = require('express');
var app = express();

var myLogger = function (req, res, next) {
  console.log('LOGGED');
  next();
};

app.use(myLogger);

app.get('/', function (req, res) {
  res.send('Hello World!');
});

app.listen(3000);

클라이언트가 루트 요청(ex.http://localhost:3000/)롤 요청을 보냈을 때 myLogger를 먼저 거치고 myLogger는 다음 미들웨어 호출(next())함수를 지정하여 res.send("Hello World"); 코드가 담긴 미들웨어로 넘어가는 코드이다

req, res 객체 변경 기능이라느 의미는 다음 코드를 보자

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

var requestTime = function (req, res, next) {
  req.requestTime = Date.now(); //req, res 객체 변경 기능
  next();
};

app.use(requestTime);

app.get('/', function (req, res) {
  var responseText = 'Hello World!';
  responseText += 'Requested at: ' + req.requestTime + '';
  res.send(responseText); //요청-응답 주기를 종료(res methods)
});

app.listen(3000);

requestTime 미들웨어는 req 객체 안에 requestTime이라느 프로퍼티를 만들었고 다음 미들웨어에서 프로퍼티 값을 가져올 수 있다

요청-응답 주기를 종료(res methods)한다는 의미는 앞서 배웠던 response의 method를 이용하여 클라이언트에게 응답을 전송한다는 의미이다. (응답 전송시 종료)
위의 코드는 res.send(response.Text);가 주기를 종료한다는 의미이다

<MiddleWare의 유형>

  1. 어플리케이션 미들웨어
  2. 라우터 레벨 미들웨어
  3. 오류처리 미들웨어
  4. 씨드파티 미들웨어

(1) 어플리케이션 미들웨어

app.use() 및 app.Method()함수("method:get.post 등")를 이용하여 app 오브젝트의 인스턴스에 바인드 시키고 미들웨어를 어플리케이션 영역에서 지정한 path대로 기능하는 것을 말한다

var app = express();

app.use(function (req, res, next) {
  console.log('Time:', Date.now());
  next();
});
var app = express();

app.use(function (req, res, next) {
  console.log('Time:', Date.now());
  next();
});

다음과 같이 특정 경로나 http methods 에 대해서만 적용할 수도 있다
이 함수들은 /user/:id 경로에 대해 미들웨어를 실행한다

// 모든 /user/:id 요청에 대해 작동
app.use('/user/:id', function (req, res, next) {
  console.log('Request Type:', req.method);
  next();
});

// /user/:id인 GET 요청에 대해서만 응답
app.get('/user/:id', function (req, res, next) {
  res.send('USER');
});

다음은 하나의 경로를 통해 일련의 미들웨어 함수를 하나의 마운트 위치에 로드하는 예가 표시되어 이싿 위에 실행 후 다음 미들웨어가 이어 받는다

app.use('/user/:id', function(req, res, next) {
  console.log('Request URL:', req.originalUrl);
  next();
}, function (req, res, next) {
  console.log('Request Type:', req.method);
  next();
});

(2) 라우터 레벨 미들웨어

라우터 레벨 미들웨어는 express.Router() 인스턴스에 바인드된다는 점을 제외하면 어플리케이션 쪽하고 동일한 방식이다

Router 객체를 이용 router.use() router.Method() 함수를 사용하면 라우터 레벨 미들웨어로 로드한다

Router 그 자체가 미들웨어 처럼 움직이므로 app.use() 의 인수로 사용되거나 다른 router.use()의 메소드로도 활용될 수 있다

var router = express.Router()롤 Router 객체를 생성한 뒤 app.use()를 사용해 마운트 시켜야 사용 가능하다

app.use에서 지정한 경로와 같은 것이 들어온다면 모두 적용시켜버리기 때문에 중복이 될 가능성이 있다
예를 들어 ('/apple',)이 있다면 /apple. /apple/user, /apple/user.images 등에 모두 적용시켜 버린다

router를 사용하는 이유는 특정 root url을 기점으로 기능이나 로직별 라우팅을 나눠서 관리할 수 있다는 점이다 그리고 user 라우터에는 다른 라우터에는 필요없는 인증 미들웨어를 따로 추가하는 작업을 할 수 있다

(3) 에러 헨들링

에러 헨들링을 하는 미들웨어는 4개의 인자를 사용해서 정의하도록 한다 (err,req,res,next)
단순한 에러 핸들링 미들웨어는 에러를 다루기 위한 미들웨어이다

(4) 서드 파티 미들웨어

기능적으로 express.app에 미들웨어를 추가하기 위해 서드파티 미들웨어 사용을 권고한다
Node.js 모듈을 사용하고 싶으면 application 레벨이든 router 레벨이든 로드해서 사용하면 된다

profile
모든지 재밌게

0개의 댓글