-req, res, next를 가진 함수를 작성시 해당 함수는 미들웨어로 동작.
-Route Handler도 미들웨어의 한 종류.
-Route Handler는 라우팅 함수(get/post/put/delete등)에 적용된 미들웨어로 일반적인 미들웨어와 다르게 path parameter를 사용 가능.
const logger = (req, res, next) =>{
console.log(`Request ${req.path}`);
next();
}
const auth = (req, res, next) => {
if(!isAdmin(req)) {
res.send("not identified");
return;
}
next();
}
-next() 함수가 호출되지 않으면 미들웨어 사이클이 멈추게 되므로 주의해야한다.
적용되는 위치에 따라서 어플리케이션/라우터/오류처리 미들웨어로 분류 가능하다.
필요한 동작 방식에 따라 미들웨어를 적용할 위치를 결정해야한다.
-app 객체에 use나 http 메소드를 사용하는 형태는 어플리케이션 미들웨어.
-app.use 나 app.http 메소드를 사용하여, 미들웨어를 설정한 path 대로 처리가능하게 할 수 있다.
-모든 요청에 공통적으로 미들웨어를 적용.
-HTTP 요청이 들어온 순간부터 적용된 순서대로 동작한다.
-app.http메소드 : ex) app.get() , app.post() , … : 얻기 get 작성 post 제거 delete...
//동작 순서는 번호로 표기.
// 화살표 쳐진 부분이 미들웨어 적용 부분
①
app.use→(req, res, next) =>{
console.log(`Request ${req.path}`);
next();
})←;
②
app.use(→auth←);
//http 요청은 여기서 받음
③
app.get('/', →(req,res,next)=>{
res.send('hello there');
}←);
-특정 경로나, 특정 http 메소드에 대해서 미들웨어를 적용할 수 있다.
// 모든 /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();
});
-Router객체를 이용해, 특정 최상위(루트) url을 기점으로 기능이나 로직별로 경로를 나누는 라우팅을 적용할 수 있다.
-var router = express.Router()로 Router 객체를 생성한 뒤에 app.use()를 사용해 마운트 시켜야지만 사용가능하다.
-특정 경로의 라우팅에만 미들웨어를 적용하는 방법 : 라우팅을 통해 각 경로마다 기능과 로직을 달리한다.
-ex) /users 경로에는 회원가입과 로그인에 대해 요청받을 것이므로 인증을 거치는 미들웨어를 추가한다.
-app.use()에서 지정한 경로와 같은 것이 들어온다면 모두 적용시켜버리기 때문에 중복이 될 가능성이 있다.
-예를 들어 app.use('/apple', ...) 이 있다면 /apple, /apple/images, /apple/images/news 등 하위 경로에 모두 적용시켜 버린다
-router 객체에 미들웨어가 적용되는 것 외에 어플리케이션 미들웨어와 동일하게 사용한다.
-app 객체에 라우터가 적용되는 것이 먼저고 이후에 순서대로 동작함.
//동작 순서는 번호로 표기.
// 화살표 쳐진 부분이 미들웨어 적용 부분
const { Router } = require('express');
const router = Router();
//3,4 에서 라우터는 선언된 상태고 라우터에 미들웨어도 연결되었음
③
router.use(→auth←);
//http 요청 받음
④
router.get('/', →(req,res,next)=>{
res.send('hello there');
}←);
// app.use에 연결된 어플리케이션 미들웨어(1번)가 먼저 수행
②
app.use→(req, res, next) =>{
console.log(`Request ${req.path}`);
next();
})←;
//app 객체에 admin path로 라우터 적용.
①
app.use('admin', →router←);
-use나 http method 함수에 여러 개의 미들웨어를 동시에 적용 가능함
-주로 한개의 경로에 특정해서 미들웨어를 적용하기 위해 사용
-전달된 인자의 순서 순으로 동작
//미들웨어 1 그다음 2 순으로 동작
app.use(→middleware1←, →middleware2←, ...);
app.use('/admin', →auth←, adminRouter);
app.get('/', →logger←, (req,res,next)=>{
res.send('hello there');
});
-미들웨어나 라우터 헨들러에서 작업을 수행할 때 에러가 발생할 경우 해당 에러를 catch해서 오류에 대해 어떻게 처리할 것인지를 정의하는 미들웨어이다.
-항상 4개의 파라미터가 필요하다 : ( err, req, res, next ) err 매개변수가 가장 앞에 있다.
-일반적으로 가장 마지막에 위치하는 미들웨어.
-다른 미들웨어가 next()에 인자를 전달(에러를 넘기면)하면 중간의 다른 미들웨어는 뛰어 넘고 오류 처리 미들웨어가 실행된다.
-오류처리 미들웨어가 없으면 next로 에러를 넘겨주었을 때, 처리할 부분이 없어 서버가 죽는다. 필수작성.
①
app.use(err, req, res, next) => {
if(!isAdin(req)) {
next(new Error('not identified'));
return;
}
next();
});
app.get('/', (req, res, next) =>{
res.send('hello there');
});
//1번에서 에러를 next로 넘겼으니 중간 건너뛰고 2번 실행
//app.use를 작성 후 파라미터, res.send를 사용.
②
app.use(err, req, res, next) => {
res.status(500).send('Error !!');
});
-하나의 미들웨어를 작성하고 작동 모드를 선택하면서 사용하고 싶을 경우 미들웨어를 함수형으로 작성하여 사용할 수 있음.
-ex) API별로 사용자의 권한을 다르게 제한하고 싶은 경우
-미들웨어에 값을 설정하고 싶을 때 함수형으로 작성.
//auth 실행시 파라미터에 따라 동작이 결정됨.
const auth = (memberType) => {
//화살표 함수식으로 작성하여 파라미터를 넣을 수 있게 만들고 그 리턴 안에 미들웨어를 작성
reutrn (req, res, next) => {
//파라미터를 확인하는 함수를 통해 멤버 타입이 일치하지 않으면 에러 처리
if(!memberCheck(req, memberType)) {
next(new Error(`this member is not ${memberType}`));
return;
}
next();
}
}
//동일 로직 다른 설정값(파라미터)
app.use('/admin', auth('admin'), adminRouter);
app.use('/users', auth('member'), userRouter);
-auth 함수는 미들웨어를 반환하는 함수.
-auth 실행시 미들웨어의 동작이 결정되는 방식으로 작성되어 있음.
-일반적으로 동일한 로직에 설정 값만 다르게 미들웨어를 사용하고 싶을 경우에 활용 됨.
-앱에 기능을 추가할 때 사용하는 미들웨어들. 이미 만들어져 라이브러리로 제공됨.
-Express.js 홈페이지나 npm 온라인 저장소에서 검색 가능.. ex) cors, multer, passport
-필요한 기능을 위한 Node.js 모듈을 설치한 후, 애플리케이션 레벨 또는 라우터 레벨에서 해당 모듈을 앱에 로드한다. npm을 추가하여 사용할 수 있다.
ex ) body-parser