Back Ground

Node - Express 커스텀 미들웨어 만들기 본문

Javascript/Node.js

Node - Express 커스텀 미들웨어 만들기

Back 2019. 2. 26. 00:03



먼저, 기본 setting을 해준다.

 https://backback.tistory.com/331


커스텀 미들웨어 만들기

요청이 들어올때 콘솔에 메시지를 찍는 단순한 미들웨어를 만들어보자.



logeer보다 위에 다음 코드를 적어준다.


app.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
app.set('views', path.join(__dirname, 'views'));
app.set('view engine''pug');
 
app.use(function(req,res,next){
  console.log(req.url, '저도 미들웨어입니다');
  next();
});
 
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
 
app.use('/', indexRouter);
app.use('/users', usersRouter);
 
cs


요청 두 개, 즉 GET /와 GET /stylesheets/style.css가 서버로 전달되었다.

각각의 요청이 모두 방금 만든 커스텀 미들웨어를 작동시켰다.

이렇게 서버가 받은 요청은 미들웨어를 타고 라우터까지 전달된다.



[주의사항]

반드시 미들웨어 안에서 next()를 호출해야 다음 미들웨어로 넘어간다.

next()는 미들웨어 흐름을 제어하는 핵심적인 함수





[ next()내장 되어져 있는 것들 ]

logger express.json, express.urlencoded, cookieParser, express.static 모두 내부적으로

next()를 호출하므로 다음 미들웨어로 넘어갈수 있다.



app.js

1
2
3
4
5
(...)
app.use(function(req,res,next){
  console.log(req.url, '저도 미들웨어입니다');
});
(...)
cs

만약 이렇게 next()없에고 실행 하고 브라우저로 접속을 하면


[콘솔 결과]

/[경로] 저도 미들웨어입니다


이렇게 멈춰 있을 것이다. ( Ctrl + C 로 나온 뒤 재 시작 해야함. )





next함수에는 몇 가지 기능이 더 있다.

인자의 종류로 기능이 구분된다.


- 인자를 아무것도 넣지 않으면 단순하게 다음 미들웨어로 넘어간다.


- next함수의 인자로 route를 넣으면  특수한 기능을 한다


- route외의 다른값을 넣으면 

  다른 미들웨어나 라우터를 건너 뛰고 바로 에러 핸들러로 이동한다.

  (넣어준 값은 에러에 대한 내용으로 간주)




next의 동작



익스프레스가 생성해주는 에러 핸들링 미들웨어를 보면 이해하기 쉽다.

가장 흔한 에러가 404에러이다.

라우터에 등록되지 않은 주소로 요청이 들어올 때 발생한다.

이 경우에는 404 NOT FOUND 상태 코드를 응답해주어야 한다.



app.js (404 NOT FOUND)

1
2
3
4
// 404 처리 
app.use(function(req, res, next) {
  next(createError(404));
});
cs

라우터 다음에 나오는 이 부분이 404에러를 만들어내는 미들웨어이다.

라우터에서 요청이 처리되지 않으면( 일치하는 주소가 없다면 )

요청은 라우터 다음에 위치한 이 미들웨어로 오게 된다.

http-errors(createError) 패키지 404 에러를 만들어내고,

에러를 next에 담에 에러 핸들러로 보내고 있다.

app.js ( 에러 헨들링 )

1
2
3
4
5
6
7
8
9
10
// 에러 핸들러
app.use(function(err, req, res, next) {
  // set locals, only providing error in development
  res.locals.message = err.message;
  res.locals.error = req.app.get('env'=== 'development' ? err : {};
 
  // render the error page
  res.status(err.status || 500);
  res.render('error');
});
cs


이 미들웨어의 내용은 템플릿 엔진을 다룰 때 배운다.

다른 미들웨어와 다르게 함수의 매개변수가 네 개이다. 

req전에 err라는 매개변수가 추가되었다.


next함수에 넣어준 인자가 err매개변수로 연결 된다.


에러 핸들링 미들웨어는 일반적으로 미들웨어 중 제일 아래에 위치하여 위에 있는 

미들웨어에서 발생하는 에러를 받아서 처리한다.








app.use


이번에는 app.use의 응용 방법에 대해서 알아보겠다.

하나의 use에 미들웨어를 여러 개 장착 할 수 있다.


순서대로 실행된다.

1
2
3
4
5
6
7
8
9
10
app.use('/'function(req,res,next){
    console.log('첫 번째 미들웨어');
    next();
}, function(req,res,next){
    console.log('두 번째 미들웨어');
    next();
}, function(req,res,next){
    console.log('세 번째 미들웨어');
    next();
});
cs


이 성질을 활용하여 Express-generator가 생성한 코드도 다음과 같이 줄일 수 있다.


1
2
3
4
5
app.use(logger('dev'),
express.json(), 
express.urlencoded({extended: false}),
cookieParser(), 
express.static(path.join(__dirname,'public'));
cs


가독성이 좋지 않아 이렇게 잘 사용하지 않지만,

유효한 코드이다.


 next를 호출하지 않으면 다음 미들웨어로 넘어가지 않는다는 

성질을 사용하여 다음 같은 미들웨어도 만들 수 있다.


1
2
3
4
5
6
7
8
9
10
app.use(function(req,res,next){
    if(+new Date() % 2 === 0){
        return res.status(400).send('50% 실패');
    }else{
        next();
    }
},function(req,res,next){
    console.log('50% 성공');
    next();
});
cs


50% 확률(숫자를 2로 나눈 나머지가 항상 1이거나 0 임을 이용)로 

404 Not Found를 응답하거나 다음 미들웨어로 넘어가는 미들웨어이다.

이 미들웨어 자체는 크게 의미 없지만, 

나중에 로그인한 사용자인지 확인할 때 위의 코드를 응용하게 된다.







그럼 Express에서 사용되는 다른 미들웨어에 대해서도 알아본다


- morgan

https://backback.tistory.com/335



- body-parser

https://backback.tistory.com/336



- static

https://backback.tistory.com/338



- express-session

https://backback.tistory.com/339








출처 : node.js 교과서

Comments