1. Middleware (미들웨어)
1) 미들웨어(Middleware)란
미들웨어는 익스프레스(Express)의 핵심 기능으로,
요청(req)과 응답(res) 사이에서 해당 정보를 이용해 필요한 처리를 수행하는 함수를 말한다.
미들웨어는 요청 객체인 req와 응답 객체인 res 파라미터를 전달받아 사용할 수 있으며,
다음 미들웨어로 넘길 수 있는 next 객체도 전달받는다.
미들웨어는 순차적으로 실행되며,
여러 개의 미들웨어를 사용하기 위해선 각각의 미들웨어 안에서 next() 메서드를 호출해야 한다.
next() 메서드가 호출되면, 해당 미들웨어 안의 콜백함수의 코드가 모두 실행되고 그다음 미들웨어로 연결된다.
const myLogger = (req, res, next) => {
console.log('LOGGED');
next();
};
req, res, next를 인자로 가진 함수는 미들웨어로 동작할 수 있다.
next 메서드의 경우 이름을 꼭 'next'로 하지 않아도 되지만, 헷갈리기 쉽게 때문에 3번째 인자에는 보통 next를 사용한다.
2) 미들웨어(Middleware) 종류
미들웨어에는 애플리케이션 미들웨어, 라우터 미들웨어, 오류 처리 미들웨어, 써드파티 미들웨어로 나뉜다.
① 애플리케이션 미들웨어 (Application Middleware)
const app = express();
app.use((req, res, next) => {
console.log('Time:', Date.now());
next();
});
app.get((req, res, next) => {
res.send(req);
})
애플리케이션 미들웨어는 app.use() 및 app.METHOD() 함수(GET, PUT, POST 등)를 통해 사용할 수 있다.
*app.use()
어떤 메서드를 사용하던, 어떤 경로로 가던 항상 미들웨어가 실행된다.
따라서 전체 함수에 적용하고 싶은 것이 있다면, app.use()를 사용하면 된다.
app.get('/', (req, res, next) => {
console.log('처음')
}, (req, res, next) => {
console.log('처음_2')
});
app.get('/', (req, res, next) => {
console.log('두번째')
})
또한, 애플리케이션 미들웨어의 경우 배열의 형태로 여러 가지 미들웨어를 등록할 수 있다.
② 라우터 미들웨어 (Router Middleware)
const route = express.Router();
app
.route('/posts')
.get((req, res, next) => {
res.status(201).send('GET: /posts');
}) //체이닝이 가능 > 체이닝 하는 경우, 경로를 다시 쓸 필요 없음
.post((req, res) => {
res.status(201).send('POST: /posts');
});
라우터 미들웨어는 express.Router() 인스턴스에서 바인드 된다는 점을 제외하면,
애플리케이션 미들웨어 (Application Middleware)와 동일하게 작동한다.
라우터를 사용하면 체이닝을 통해 경로를 다시 입력하지 않아도 되기 때문에 좀 더 편하게 사용할 수 있다.
단, 위 경우보다 복잡한 경우엔 가독성이 좋지 않기 때문에 따로 라우터를 지정해서 사용하는 것이 좋다.
app.use()에서 지정한 경로와 같다면 모두 적용되기 때문에, 중복 가능성이 있으므로 주의해야 한다.
Router 객체는 그 자체가 미들웨어처럼 움직이기 때문에 app.use()의 인수로 사용될 수도 있으며,
다른 router의 use() 메서드에서 사용될 수도 있다.
③ 오류 처리 미들웨어 (Error-handling Middleware)
app.use((error, req, res, next) => {
console.error(error);
res.status(500).json({ message: 'error' });
});
에러 처리 미들웨어도 다른 미들웨어와 동일한 방법으로 함수를 정의하지만, (error, req, res, next) 4개의 인자를 받는다.
app.use() 및 라우트 호출을 정의한 후 맨 마지막에 사용해야 한다.
④ 기본 제공 미들웨어 (Built-in Middleware)
4.x 버전 이후부터는 기본 제공 미들웨어에 express.static만 존재한다.
express.static은 정적 파일을 전달해 주는 역할을 한다.
app.use(express.static('public')); //public = 폴더이름
원래라면 특정 파일에 접근하기 위해선 경로를 다 적어야 한다.
그러나 static을 이용하면, 폴더 이름을 적는 것만으로도 해당 폴더에 있는 정보에 접근이 가능하다.
const options = {
dotfiles: 'ignore', //숨겨진 파일은 무시하도록 지정
etag: false,
index: false,
maxAge: '1d',
redirect: false,
setHeaders: function (res, path, stat) {
res.set('x-timestamp', Date.now());
},
};
app.use(express.static('public', options));
static엔 위와 같은 다양한 옵션이 존재한다.
⑤ 써드파티 미들웨어 (Third-party Middleware)
써드파티 미들웨어는 express에서 자체적으로 제공하지 않고, 따로 설치해야 하는 미들웨어를 의미한다.
대표적으로 helmet이나 cookie-parser 같은 모듈이 해당된다고 볼 수 있다.
npm i helmet
app.use(helmet())
helmet은 보안에 필요한 header를 자동으로 추가해 주는 미들웨어를 의미한다.
npm i cookie-parser
import cookieParser from 'cookie-parser'
app.get('/', (req, res) => {
console.log(req.cookies);
res.send('hello')
})
app.listen(8080)
cookie-parser은 쿠키를 볼 수 있도록 해주는 미들웨어이다.
key를 사용해 쿠키 값에 접근하는 것도 가능하다.