미들웨어의 기본 개념은 이렇습니다.
‘누군가가 만든 소프트웨어를 부품으로 해서 나의 소프트웨어를 개발한다!’
미들웨어를 등록해보기도 하고 직접 만들어보기도 하면서 이해를 해봅시다!
Express에서 유명한 ‘body-parser’라는 미들웨어를 이용해 볼 것입니다!
일단 패키지를 설치해주시고 전체 코드를 복사해서 붙여 넣어주세요.
npm install body-parser
const express = require('express'); const app = express(); const bodyParser=require('body-parser'); // 미들웨어 등록하기 app.use(bodyParser.urlencoded({extended:false})); // (body-parser가 만들어낸 미들웨어를 불러오는 표현식) // 미들웨어 만들고 등록하기 app.use(function(req,res,next){ req.language='javascript'; next(); }, function(req,res,next){ req.framework='express'; next('route'); } ); // '/'라우트: 라우팅을 처리하는 메소드 (url을 통해'/'가 요청으로 올 때 처리함) app.get('/', function (req, res, next) { res.send(`<form action="process" method="post"> <p> <input type="text" name="title" placeholder="title"> </p> <p> <textarea rows="4" cols="50" name="description" placeholder="description"></textarea> </p> <p> <input type="submit"> </p> </form> `); }); // 등록한 미들웨어의 기능 이용하기 app.post('/process',function(req,res,next){ let post = req.body; let title=post.title; let description=post.description; let language = req.language; let framework = req.framework; res.send(`${title} ${description} ${language} ${framework}`); }); app.listen(2000, function(){ console.log('2000!'); });
위 코드를 하나 하나 살펴 보겠습니다!!
const bodyParser=require('body-parser'); // 미들웨어 등록하기 app.use(bodyParser.urlencoded({extended:false})); // (body-parser가 만들어낸 미들웨어를 불러오는 표현식)
먼저 남이 만든 미들웨어를 등록하는 방법입니다!
미들웨어가 포함된 모듈을 불러오고, app.use메소드의 인수에 미들웨어를 불러오는 표현식을 추가하면 됩니다. 이러한 표현식은 미들웨어를 제공하는 제3자가 제공해줍니다.
필자는 body-parser모듈을 불러오고 (여기)에서 제공하는 표현식을 이용하였습니다.
이렇게 미들웨어를 등록하면 미들웨어의 기능을 이용할 수가 있습니다.
body-parser같은 경우, post방식으로 전달한 데이터들을 request.body에 저장해주는 기능을 합니다!
앞으로는 ‘request.on이벤트’ 따위를 이용하지 않고도 form에 작성한 데이터를 쉽게 불러올 수 있습니다!
// 미들웨어 만들고 등록하기 app.use(function(req,res,next){ req.language='javascript'; next(); }, function(req,res,next){ req.framework='express'; next('route'); } );
이번에는 미들웨어를 직접 만들고 등록하는 방법입니다!
app.use메소드의 인수에 함수를 작성하였을 때, 해당 함수는 미들웨어가 되고 등록까지 됩니다.
미들웨어 함수는 크게 두 가지 기능을 가지고 있습니다!
1. request와 response객체의 멤버를 추가/변경할 수 있다.
2. next함수로 다음 미들웨어를 호출할 수 있다.
1번 기능 같은 경우, 첫 번째 미들웨어에서 request객체에 language멤버를 추가하는 부분, 두 번째 미들웨어에서 framework멤버를 추가하는 부분으로 확인이 가능합니다.
이 1번 기능으로 다른 메소드에서도 자유롭게 req.language / req.framework 멤버를 이용할 수 있게 됩니다!
2번 기능 같은 경우, next()함수와 next(‘route’)함수가 호출되는 것으로 확인이 가능합니다.
인수가 비어 있는 경우, 다음 미들웨어를 호출하고 ‘route’가 온 경우, 라우팅을 담당하는 함수를 호출하라는 의미입니다.
// '/'라우트: 라우팅을 처리하는 메소드 (url을 통해'/'가 요청으로 올 때 처리함) app.get('/', function (req, res, next) { res.send(`<form action="process" method="post"> <p> <input type="text" name="title" placeholder="title"> </p> <p> <textarea rows="4" cols="50" name="description" placeholder="description"></textarea> </p> <p> <input type="submit"> </p> </form> `); });
위 소스는 클라이언트가 루트 페이지를 요청할 때 응답하는 라우트입니다.
아래와 같은 form창이 담긴 html문서를 전달합니다.
// 등록한 미들웨어의 기능 이용하기 app.post('/process',function(req,res,next){ let post = req.body; let title=post.title; let description=post.description; let language = req.language; let framework = req.framework; res.send(`${title} ${description} ${language} ${framework}`); });
미들웨어들이 등록된 이후로 request객체에 body, language, framework 프로퍼티가 추가되었습니다!
이 프로퍼티들을 응답으로 전달하는 기능을 하는 라우트입니다.
실행 결과, 위와 같이 잘 동작하는 것을 확인할 수 있습니다!!
미들웨어를 등록하는 다른 메소드
위에서는 미들웨어가 app.use메소드로부터 등록이 된다고 설명했지만 항상 그런 것은 아닙니다.
app.post를 이용 시, 클라이언트 요청이 post방식일 때만 미들웨어가 등록됩니다.
app.get를 이용 시, 클라이언트 요청이 get방식일 때만 미들웨어가 등록됩니다.
app.use를 이용 시, 클라이언트 요청이 오면 미들웨어가 등록됩니다.
예를 들어, 아래와 같이 미들웨어를 등록하면 get방식을 이용하는 모든 path에서 미들웨어가 등록됩니다.
app.get('*',(request,response,next)=>{ // 미들웨어 함수 작성 });
위처럼 express모듈의 app객체를 이용해서 등록된 미들웨어는 ‘Applicaton-level middleware’ 라고 불립니다.
따지고 보면 ‘라우트’도 미들웨어를 등록하는 메소드라고 말할 수 있습니다.
그러나 이 메소드는 response.send() 명령을 통해 클라이언트에게 응답하는 것을 목표로 합니다.
또한 다른 미들웨어를 실행하지도 않고 request, response객체를 변경하지도 않기 때문에 따로 구분 짓습니다!
미들웨어의 특징
미들웨어는 순차적으로 실행되는 것이 특징입니다.
위 소스들을 기준으로 실행 순서를 따져 보면
[ bodyParser 미들웨어 -> (req.language 제작) 미들웨어 -> (req.framework 제작) 미들웨어 ->클라이언트의 요청에 따른 라우트 ]가 됩니다.
그런데 만약 클라이언트가 요청한 내용을 해결할 수 있는 라우트가 없으면 어떻게 될까요?
이런 경우 심하면 서버가 중단될 수도 있습니다.
이를 대비해서 에러 처리 미들웨어를 등록할 필요가 있습니다!
이 미들웨어는 [클라이언트의 요청을 처리할 라우트를 순차적(위->아래)으로 찾아 보았는데 없는 경우]에만 호출돼야 합니다!
따라서 포트를 지정하는 listen메소드 위에 작성하는 것이 적당합니다.
app.use((request,response,next)=>{ response.status(404).send('Cant find that!!'); });
이 미들웨어가 실행되면 HTTP Status Code로 404를 줄 뿐만 아니라 요청을 처리하는 라우트를 찾을 수 없다는 텍스트도 전달됩니다!
지금까지 미들웨어에 대해 설명을 해보았습니다.
Node.js에서 실행되는 서버 프로그램은 여러 미들웨어를 거쳐서 실행이 되는 구조입니다.
미들웨어들은 독립적이지 않고 서로 연계돼서 하나의 시스템을 이루고 있습니다.
미들웨어 강의를 해주신 선생님 말씀을 끝으로 포스팅을 마치겠습니다!
‘애플리케이션이 구동될 때 작은 프로그램들이 실행되는데, 각각의 프로그램들이 서로와 서로를 연결해주는 작은 소프트웨어라는 점에서 미들웨어이다.’
감사합니다.
Node에 관한 게시물은 CodeIt,생활코딩의 강의 내용을 정리한 글입니다. 강의 이미지나 내용 자체를 업로드하지는 않습니다!!