express.js의 Middleware

2023. 12. 15. 01:59Node.js

728x90
반응형

데브코스 강의 중 app.use() 함수를 사용하여 express.json()(json parser)를 등록하는 것을 보고 그 원리가 궁금하여 더 공부해보았다.

1. Middleware란?

Middleware는 express.js의 핵심 개념 중 하나인데

 

간단히 설명하면 클라이언트의 requestresponse 사이에 존재하여 미들웨어 자신이 담당한 기능을 마친 후

다음 미들웨어 기능으로 제어권을 넘기거나 응답을 보내는 함수들이다.

 

app의 get, post 등 route handler function 들도 미들웨어의 한 예들이다.

app.get('/', (req, res) => { 
  res.json({ id: 1, 이름: 'Ashraful' }); 
};

 

또, 클라이언트의 요청 payload에서 json을 파싱하여

request 객체의 body 프로퍼티로 초기화해주는 express.json()도 미들웨어 함수이다.

app.use(express.json());

 

이렇듯 route handle, 파싱, 로깅, 에러처리 등 request-response cycle 사이에서 개발자가 의도한 동작을 하는 함수들

모두 미들웨어라고 할 수 있다.

 

위의 그림과 같이 미들웨어 스택에 등록된 미들웨어들이 순차적으로 실행된다.

 

express에서는 미들웨어들의 종류를 다섯 가지로 정의하고 있다.

  • Application-level middleware
  • Router-level middleware
  • Error-handling middleware
  • Built-in middleware
  • Third-party middleware

2. Application-level middleware

applictaion-level 미들웨어는 app.use() 또는 app.METHOD() 함수들을 통해 app 객체에 바인딩한다.

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

//app.use()로 등록
app.use((req, res, next) => {
  console.log('do something... ');
  next();
});

//app.METHOD()로 등록
app.get('/', (req, res, next) => {
  res.send('Hello World!');
});


//배열로 등록할 수도 있다.
app.use([foo, bar]);

function foo(req, res, next) {
    console.log('foo...');
    next();
}

function bar(req, res, next) {
    console.log('bar...');
    next();
}

 

위의 코드를 보면 next() 함수가 각 미들웨어 마지막에 호출 되어있는데
next() 함수는 다음 미들웨어어 제어권을 넘겨주는 함수이기 때문에 꼭 호출해주어야한다.


3. Router-level middlware

Router-level 미들웨어는 Application-level 미들웨어와 같은 방식으로 동작하지만,

express.Router() 인스턴스에 바인딩 된다는 것이 다르다.

const express = require('express');
const app = express();
const router = express.Router();

//router.use()
router.use(function (req, res, next) {
  console.log('do something...');
  next();
});

//router.METHOD()
router.get('/foo', function (req, res, next) {
  res.json({foo : 'foo')});
});

//라우터를 app에 마운트해준다.
app.use('/', router);

 

위의 코드만 보면 app에 등록하나 router에 등록하나 무슨 차이지? 라는 의문이 들 수 있다.

 

하지만 아래의 파일들을 보면 router.use()router.METHOD()가 왜 필요한지 알 수 있다.

user.js, post.js, index.js 세 파일이 있다고 가정하자

user.js

const express = require('express');
const router = express.Router();

router.post('/', (req, res) => {    
  // ....
  res.send();
});

router.get('/:id', (req, res) => {    
  // ....
  res.send();
});

module.exports = router;

post.js

const express = require('express');
const router = express.Router();

router.get('/', (req, res) => {    
  // ....
  res.send();
});

router.post('/', (req, res) => {    
  // ....
  res.send();
});

module.exports = router;

 

각 모듈 별로 각각의 라우터 인스턴스를 생성하고 미들웨어를 바인딩해준 뒤

index.js

const express = require('express');
const posts = require('./routes/posts');
const users = require('./routes/users');

const app = express();

app.use(express.json());
app.use('/api/posts', posts);    
app.use('/api/users', users);

app.listen(3000);

 

어플리케이션의 진입점이 될 index.js에서 각 모듈들의 API를 각각 다른 경로로 마운트했다.

 

이렇게 어플리케이션의 규모가 커지면 코드를 모듈별로 분할해 관리하기 때문에 router.use()router.METHOD() 가 필요한 것이다.

 

router 인스턴스를 사용하지 않고 Application-level 미들웨어를 남발한다면 코드를 추적하기 매우 어려운 상황이 될 것이다.


4. Error-handling middlware

Error-handling 미들웨어는 다른 미들웨어와 동일하지만 3개가 아닌 4개의 argument가 있다.

function error(err, req, res, next) {
  // log it
  if (!test) console.error(err.stack);

  // respond with 500 "Internal Server Error".
  res.status(500);
  res.send('Internal Server Error');
}

 

express가 이 미들웨어가 오류처리 미들웨어라는 것을 알려면 argument가 4개여야한다.


5. Built-in middleware

express에는 버전 4.x 부터 다음과 같은 내장 미들웨어가 있다.

  • express.static html 파일, 이미지 등과 같은 정적 리소스를 제공한다.
  • express.json JSON 페이로드로 들어오는 요청을 구문 분석한다.
  • express.urlencoded URL로 인코딩된 페이로드로 들어오는 요청을 구문 분석한다.

6. Third-party middleware

기능 추가를 위해 third-party 미들웨어를 사용할 수 있다.

 

필요한 기능의 Node.js 모듈을 install 하고 해당 모듈을 application-level 또는 router-level로 바인딩하면된다.

$ npm install cookie-parser
const express = require('express');
const app = express();
const cookieParser = require('cookie-parser');

// load the cookie-parsing middleware
app.use(cookieParser());

 


참조

https://expressjs.com/en/guide/using-middleware.html#middleware.application

728x90
반응형

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

Node.js란?  (0) 2023.11.27