Notice
Recent Posts
Recent Comments
Link
«   2025/05   »
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
Archives
Today
Total
관리 메뉴

9시 24분

미들웨어 - body parser, compression, 만들기, 실행순서 본문

Javascript/Node.js

미들웨어 - body parser, compression, 만들기, 실행순서

leeeee.yeon 2021. 7. 8. 13:29

미들웨어란, 다른 사람 혹은 자신이 만든 함수로 생각하면 된다.

공식 문서 상의 정의는 '요청-응답 주기 중 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에서 자체적으로 제공하지 않는다.