조현영님의 Node.js 교과서의 내용을 공부하여 정리한 내용입니다.
6.3.1 커스텀 미들웨어 만들기
- 직접 미들웨어를 만들어보면서 미들웨어의 원리를 이해보자.
- 요청이 들어올 때 콘솔에 메시지를 찍는 단순한 미들웨어이다.
1 2 3 4 5 6 7 8 9 10 11
|
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.js 파일을 저장하고 서버를 실행한다.
1 2 3 4
| / 저도 미들웨어입니다 GET / 200 416.849 ms – 170 /stylesheets/style.css 저도 미들웨어입니다 GET /stylesheets/style.css 200 10.119 ms - 111
|
- 요청 두 개, 즉 GET /와 GET /stylesheets/style.css가 서버로 전달되었다.
- 각각의 요청이 모두 방금 만든 커스텀 미들웨어를 작동시켰다.
- 이렇게 서버가 받은 요청은 미들웨어를 타고 라우터까지 전달된다.
주의해야 할 점!
- 반드시 미들웨어 안에서 next()를 호출해야 다음 미들웨어로 넘어간다.
- logger나 express.json, express.urlencoded, cookieParser, express.static - 모두 내부적으로는 next()를 호출하므로 다음 미들웨어로 넘어갈 수 있다.
- next()는 미들웨어의 흐름을 제어하는 핵심적인 함수이다.
next 함수의 다른 기능
- 인자의 종류로 기능이 구분된
- 인자를 아무것도 넣지 않으면 단순하게 다음 미들웨어로 넘어간다.
- next 함수의 인자로 route를 넣으면 특수한 기능을 한다.
- 이것은 라우터를 배울 때 함께 알아볼 예정
- route 외의 다른 값을 넣으면 다른 미들웨어나 라우터를 건너 뛰고 바로 에러 핸들러로 이동
- 넣어준 값은 에러에 대한 내용으로 간주됨
에러 핸들링 미들웨어
404 처리 미들웨어
익스프레스가 생성해주는 에러 핸들링 미들웨어를 보면 이해하기 쉽다.
- 가장 흔한 에러가 404 에러이다.
- 라우터에 등록되지 않은 주소로 요청이 들어올 때 발생
- 이 경우에는 404 NOT FOUND 상태 코드를 응답해주어야 한다.
1 2 3 4
| app.use(function(req, res, next) { next(createError(404)); });
|
- 라우터 다음에 나오는 이 부분이 404 에러를 만들어내는 미들웨어
- 라우터에서 요청이 처리되지 않으면(일치하는 주소가 없다면) 요청은 라우터 다음에 위치한 이 미들웨어로 오게 된다.
- http-errors(createError) 패키지가 404 에러를 만들어내고, 이 에러를 next에 담아 에러 핸들러로 보내고 있다.
에러 핸들러
1 2 3 4 5 6 7 8
| app.use(function(err, req, res, next) { res.locals.message = err.message; res.locals.error = req.app.get("env") === "development" ? err : {};
res.status(err.status || 500); res.render("error"); });
|
- 이 미들웨어의 내용은 템플릿 엔진을 다룰 때 배울 예정
- 다른 미들웨어와 다르게 함수의 매개변수가 4개
- req 전에 err라는 매개변수가 추가됨
- next 함수에 넣어준 인자가 err 매개변수로 연결된다.
- 에러 핸들링 미들웨어는 일반적으로 미들웨어 중 제일 아래에 위치하여 위에 있는 미들웨어에서 발생하는 에러를 받아서 처리한다.
app.use의 응용 방법
- 하나의 use에 미들웨어를 여러 개 장착할 수 있다.
- 순서대로 실행된다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| app.use( "/", function(req, res, next) { console.log("첫 번째 미들웨어"); next(); }, function(req, res, next) { console.log("두 번째 미들웨어"); next(); }, function(req, res, next) { console.log("세 번째 미들웨어"); next(); } );
|
- 이 성질을 활용하여 Express-generator가 생성한 코드도 다음과 같이 줄일 수 있다.
1 2 3 4 5 6 7
| app.use( logger("dev"), express.json(), express.urlencoded({ extended: false }), cookieParser(), express.static(path.join(__dirname, "public")) );
|
가독성이 좋지 않아 이렇게는 잘 사용하지 않지만, 유효한 코드이다.
next를 호출하지 않으면 다음 미들웨어로 넘어가지 않는다는 성질을 사용하여 다음과 같은 미들웨어도 만들 수 있다.
1 2 3 4 5 6 7 8 9 10 11 12 13
| app.use( function(req, res, next) { if (+new Date() % 2 === 0) { return res.status(404).send("50% 실패"); } else { next(); } }, function(req, res, next) { console.log("50% 성공"); next(); } );
|
- 50% 확률(숫자를 2로 나눈 나머지가 항상 1이거나 0임을 이용)로 404 Not Found를 응답하거나 다음 미들웨어로 넘어가는 미들웨어
- 이 미들웨어 자체는 크게 의미가 없지만, 나중에 로그인한 사용자인지 확인할 때 위의 코드를 응용하게 된다.
다음 시간에는 Express에 사용되는 다른 미들웨어에 대해서도 알아보자.