Express의 미들웨어
미들웨어란, req(요청) 객체, res(응답) 객체, 그리고 어플리케이션 요청-응답 사이클 도중 그 다음의 미들웨어 함수에 대한 엑세스 권한(next)을 갖는 함수
클라이언트에게 요청이 오고 그 요청을 보내기 위해 응답하려는 중간(미들)에 목적에 맞게 처리를 하는, 말하자면 거쳐가는 함수들이다.
미들웨어를 통해 웹 서버의 요청/응답에 대해 공통적으로 관리가 가능
예를 들어 모든 요청에 대해서 로그를 남겨 확인하고 싶은 경우, 승인된 사용자만 API를 접근할 수 있게 만들고 싶을때 미들웨어를 통해 쉽게 구현 가능하다
참고로 유명한 웹서버인 Apache(아파치), Nginx(엔진x)경우 미들웨어 대신 모듈의 개념을 가지고 있다.
express의 미들웨어와 개념과 기능이 매우 유사하다.
미들웨어 구현
app.use((req, res, next) => {
// 필요한 코드
});
req : 요청에 대한 정보가 담겨있는 객체
res : 응답을 위한 기능이 제공
next : 다음 스택으로 정의된 미들웨어를 호출함
미들웨어에는 순서가 있고, 코드의 상단에 있을 수록 먼저 실행된다. 하단의 미들웨어의 경우 next 함수를 이용해서 다음 미들웨어로 현재 요청을 넘길 수 있다.
next라는 말에서 알 수 있듯이 next를 통해 미들웨어는 순차적으로 처리된다. (순서가 중요)
// Request 로그 남기는 미들웨어 작성
app.use((req, res, next) => {
console.log('Request URL:', req.originalUrl, ' - ', new Date());
next();
});
위 미들웨어를 지날때마다 req 경로를 콘솔로 찍어주고 next()를 통해 다음 미들웨어로 넘어간다.
미들웨어 4가지 유형
어플리케이션 레벨 미들웨어
라우터 레벨 미들웨어
오류처리 미들웨어
써드파티 미들웨어
어플리케이션 레벨 미들웨어
express()로 생성할 수 있는 app 객체의 app.use()나 app.METHOD()(ex. app.get, app.post) 함수를 이용해 미들웨어를 app 인스턴스에 바인딩하는 미들웨어
마운트 경로가 없는 미들웨어 함수는 앱이 요청을 수신할 때마다 실행하게 된다.
//마운트 경로가 있으며 다음 미들웨어 함수를 호출함
app.get('/pages/', (req, res, next) => {
console.log('Time : ', Date.now());
next();
});
//마운트 경로가 없으며 응답을 여기서 끝냄
app.get((req, res, next) => {
console.log('Not Found');
});
라우터 레벨 미들웨어
express.Router()로 생성할 수 있는 router 인스턴스에 미들웨어가 바인딩된다.
그것 외에는 애플리케이션 레벨 미들웨어가 차이가 없다.
//app.js
const express = require('express');
const app = express();
const pageRouter = ('./routes/pages');
app.use('/pages', pageRouter);
//pages.js
const express = require('express');
const router = express.Router();
router.get('/pages/:id', (req, res, next) => {
//pages id가 0이면 'regular'가 아닌 'special'로 넘어감
if (req.params.id == 0) next('route');
//pages id가 0이 아니라면 'regular'로 넘어감
else next();
}, (req, res, next) => {
res.send('regular');
}
});
//pages id가 0일 때 넘어올 미들웨어
router.get('/pages/:id', (req, res, next) => {
res.send('special');
}
module.exports = router;
const router = express.Router()로 Router 객체를 생성한 뒤에 app.use()를 사용해 마운트 시켜야지만 사용가능하다.
app.use()에서 지정한 경로와 같은 것이 들어온다면 모두 적용시켜버리기 때문에 중복이 될 가능성이 있다.
router를 사용하는 이유는 특정 root url을 기점으로 기능이나 로직별로 라우팅을 나눠서 관리할 수 있다는 점이다.
user 라우터에는 다른 라우터에는 필요없는 인증 미들웨어를 따로 추가하는 등의 작업을 할 수 있다.
오류처리 미들웨어
(err, req, res, next)를 인자로 받고, 항상 4개의 매개변수가 필요하다.
err.stack으로 에러 메시지를 볼 수 있다.
//오류의 종류에 상관없이 모든 오류를 잡는 미들웨어
app.get((err, req, res, next) => {
console.log(err.stack);
res.status(500).send('Something broke!');
});
주의할 점은 오류 처리 미들웨어는 app.use() 및 라우트 호출을 정의한 뒤 거의 코드의 맨 끝에 정의해야 한다는 점이다.
app.get('/pages/:id', (req, res, next) => {
if (!req.params.id) next(err);
});
명시적으로 next(err)를 해줘야 오류 처리 미들웨어로 넘어갈 수 있다.
써드파티 미들웨어
npm 에서 설치한 helmet이나 cookie-parser 같은 모듈들이 해당이 된다.
express 자체적으로 제공하지 않고 따로 설치해야 하는 것들은 다 써드파티라고 보면 된다.
npm i cookie-parser
const express = require('express');
const app = express();
const cookieParser = require('cookie-parser');
app.use(cookieParser());
'coding > Node.js' 카테고리의 다른 글
모듈(module), require(), IIFE (0) | 2022.08.03 |
---|---|
sequelize CRUD 사용법 (0) | 2022.08.02 |
package.json (0) | 2022.07.31 |
npm jsonwebtoken (0) | 2022.07.29 |
Node.js, express (0) | 2022.07.22 |