9시 24분
미들웨어 - body parser, compression, 만들기, 실행순서 본문
미들웨어란, 다른 사람 혹은 자신이 만든 함수로 생각하면 된다.
공식 문서 상의 정의는 '요청-응답 주기 중 req, res 객체에 대한 접근 권한을 갖고 변형시킬 수 있으며 미들웨어 스택 내 다음 미들웨어 함수에 대한 접근 권한을 next라는 인자로 갖는 함수'라고 되어 있다.
body-parser과 compression이라는 미들웨어를 사용해보고,
미들웨어를 직접 만들어보고,
미들웨어의 실행순서에 대해 알아보자.
body-parser
create_process를 보자.
var body = '';
request.on('data', function(data){
body = body + data;
});
request.on('end', function(){
var post = qs.parse(body);
var title = post.title;
var description = post.description;
db.query(`
INSERT INTO topic (title, description, created, author_id)
VALUES(?, ?, NOW(), ?)`,
[post.title, post.description, post.author],
function(error, result){
if(error) throw error;
response.writeHead(302, {Location: `/?id=${result.insertId}`});
response.end();
}
);
});
post 방식으로 데이터를 전달받을 때는 큰 데이터가 들어올 수 있다.
기존에 사용하는 방식은 body 변수에 request.on으로 데이터를 추가하는 방식이었다. 이번에는 body-parser을 사용하여 이 코드를 더 간결하게 만들어보자.
npm install body-parser --save
생활코딩 영상에서는 body-parser을 설치하지만, 이제는 body parser을 설치하지 않고도 사용할 수 있어 영상과 달리 아래의 코드로 body-parser을 사용해주었다.
app.use(express.urlencoded({extended:false}));
첫 미들웨어 사용인데, 여기서 우리는 app.use() 함수로 미들웨어를 사용할 수 있다는 것을 알 수 있다.
body-parser은 body라는 property를 자동으로 만들어준다.
그렇기 때문에 request.on('data') request.on('end') 같은 request.on() 함수가 필요 없고, post 변수를 request.body로 해주면 된다. create_process 메서드를 수정하면 아래와 같다.
exports.create_process = function(request, response){
var post = request.body;
var title = post.title;
var description = post.description;
var author = post.author;
db.query(`
INSERT INTO topic (title, description, created, author_id)
VALUES(?, ?, NOW(), ?)`,
[title, description, author],
function(error, result){
if(error) throw error;
response.redirect(`/page/${result.insertId}`);
}
);
}
update_process랑 delete_process도 수정해주자
exports.update_process = function(request, response){
var post = request.body;
var id = post.id;
var title = post.title;
var description = post.description;
var author = post.author;
db.query(`UPDATE topic SET title=?, description=?, author_id=? WHERE id=?`,
[title, description, author, id],
function(error, result){
if(error) throw error;
response.redirect(`/page/${id}`);
});
}
exports.delete_process = function(request, response){
var post = request.body;
var id = post.id;
db.query(`DELETE FROM topic WHERE id=?`, [post.id], function(error, result){
if(error) throw error;
response.redirect('/');
});
}
( + 테스트 과정에서 궁금증이 생겨 해봤는데 이모지를 입력하면 에러가 생긴다 🤔 )
compression
이름에서 알 수 있듯이 압축 데이터가 너무 많으면 용량이 커
데이터를 압축해서 압축된 데이터를 전송하여 시간/비용을 줄일 수 있다.
npm install compression --save
const compression = require('compression');
app.use(compression());
compression 미들웨어를 설치하면 끝이다. 따로 코드를 수정하는 과정이 없다.
+ 그리고 하는 김에 require하는 변수들은 const형으로 다 바꿔주었다.
미들웨어 만들기
함수를 만들고 app.use하면 된다. 그냥 함수와 다른 점은 next라는 인자가 추가된다는 것이다.
그리고 next라는 변수에는 그 다음에 호출되어야 할 미들웨어가 담겨있다.
영상에서는 파일을 다루는 함수를 미들웨어로 만들었는데 내 코드에서는 MySQL을 이용하기 때문에 해당 부분이 없다. 그래서 그냥 미들웨어의 형식이 어떤건지 알 수 있게 블로그에만 코드를 작성한다.
app.get('*', function(request, response, next){
fs.readdir('./data', function(error, fileList){
request.list = fileList;
next();
}
});
또, 코드들을 쭉 보면 app.get의 두번째 인자에 있는 함수 또한 미들웨어라고 할 수 있다.
미들웨어의 실행순서
미들웨어에는 애플리케이션 레벨, 라우터 레벨, 오류 처리, 기본 제공, 써드파티 미들웨어가 있다.
- 애플리케이션 레벨 미들웨어
var express = require('express')
var app = express()
app.use(function (req, res, next) {
console.log('Time:', Date.now())
next()
})
그 다음 미들웨어를 실행할지 안할지를 이전 미들웨어가 결정하도록 한다.
app.use('/user/:id', function (req, res, next) {
console.log('Request Type:', req.method)
next()
})
특정 경로에만 미들웨어가 작동할 수 있도록 한다.
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()
})
미들웨어를 여러 개 붙일 수 있다. 첫 번째 미들웨어가 실행되고 그 다음 미들웨어가 실행되는 순서로 진행된다.
app.get('/user/:id', function (req, res, next) {
console.log('ID:', req.params.id)
next()
}, function (req, res, next) {
res.send('User Info')
})
// handler for the /user/:id path, which prints the user ID
app.get('/user/:id', function (req, res, next) {
res.send(req.params.id)
})
순서에 따라 첫 번째 미들웨어(console.log)가 실행되고, next()로 그 다음 res.sent('User Info') 미들웨어가 실행되고,
res.sent('User Info')가 next를 호출하지 않으면 끝나게 된다.
app.get('/user/:id', function (req, res, next) {
// if the user ID is 0, skip to the next route
if (req.params.id === '0') next('route')
// otherwise pass the control to the next middleware function in this stack
else next()
}, function (req, res, next) {
// send a regular response
res.send('regular')
})
// handler for the /user/:id path, which sends a special response
app.get('/user/:id', function (req, res, next) {
res.send('special')
})
조건문을 통해 next가 실행될지 안될지도 결정할 수 있다.
next('route') - 다음 미들웨어를 실행해라 > res.send('special')이 실행됨
생활코딩에서는 애플리케이션 레벨 미들웨어만 자세히 설명해서 다른 미들웨어는 https://dev-dain.tistory.com/67
[Node.js] express 미들웨어란?
미들웨어 사용하기 Express 미들웨어란 무엇인가? 쉽게 말해 함수이다. Express에서는 사실상 모든 것이 미들웨어이다. 내가 이해하기로 미들웨어와 미들웨어 함수는 같은 말이다(아니라면 댓글 부
dev-dain.tistory.com
을 참고해서 작성한다.
- 라우터 레벨 미들웨어
router 객체에 미들웨어가 바인딩된다는 점 이외에는 애플리케이션 레벨 미들웨어와 차이가 없다.
router.get('/pages/:id', (req, res, next) => {
//pages id가 0이면 'regular'가 아닌 'special'로 넘어감
if (req.params.id == 0) next('route');
//pages id가 0이 아니라면 'regular'로 넘어감
else next();
}, (req, res, next) => {
res.send('regular');
}
});
//pages id가 0일 때 넘어올 미들웨어
router.get('/pages/:id', (req, res, next) => {
res.send('special');
}
- 오류 처리 미들웨어
//오류의 종류에 상관없이 모든 오류를 잡는 미들웨어
app.get((err, req, res, next) => {
console.log(err.stack);
res.status(500).send('Something broke!');
});
err, req, res, next 항상 이 4개를 인자로 받는다.
오류 처리 미들웨어는 app.use() 및 라우트 호출을 정의한 뒤 거의 코드 맨 끝에 정의해야 함을 주의하자.
위 코드는 모든 오류를 잡는 미들웨어인데 에러마다 다른 오류 처리 미들웨어 함수를 정의할 수도 있다.
- 기본 제공 미들웨어
정적 리소스를 제공할 루트 디렉토리를 정하는 express.static 같은 것이 있다.
- 써드파티 미들웨어
compression과 같이 npm에서 설치하는 미들웨어, express에서 자체적으로 제공하지 않는다.
'Javascript > Node.js' 카테고리의 다른 글
HTTP (0) | 2021.07.08 |
---|---|
정적인 파일 서비스, 에러 처리, 라우터, 보안, express generator (0) | 2021.07.08 |
페이지 생성, 수정, 삭제 (0) | 2021.07.07 |
실습 준비, 홈페이지 구현, 상세페이지 구현 (0) | 2021.07.07 |
Heroku 배포 성공 !!!! (0) | 2021.07.07 |