세리프 따라잡기

nodejs-express 미들웨어(body-parser, compression) 설치 및 사용 방법 정리, 만들기, 실행순서에 대해 본문

Node.js

nodejs-express 미들웨어(body-parser, compression) 설치 및 사용 방법 정리, 만들기, 실행순서에 대해

맑은 고딕 2021. 1. 18. 19:10

6. 미들웨어(middleware)에 대하여

소프트웨어를 만들 때 우리가 처음부터 끝까지 만드는 경우는 거의 없다. 보통은 다른 사람이 만든 소프트웨어를 부품으로 해서 나의 소프트웨어를 만들어간다. (그렇기 때문에 생산성이 높아지는 것)

쉽게 말하자면: 다른 사람(혹은 자신)이 만든 소프트웨어를 미들웨어라고 한다. 일단 남이 만든 것을 알아보자!!

expressjs.com/en/guide/using-middleware.html#middleware.third-party 를 이용해 알아보자. 여기서 third-party는 남들이 만들었다는 뜻이다. (express가 만든 오피셜이 아닌)

 

-1. body-parser : body라는 것은 웹 브라우저에서 요청한 정보의 본체를 말하고 본체를 설명하는 데이터를 헤더라고 한다. 즉 본체인 데이터를 parser(분석)해서 필요한 형태로 가공해주는 프로그램이다.

 

expressjs.com/en/resources/middleware/body-parser.html 를 통해 우리가 해볼 body-parser라는 미들웨어를 설치 및 사용해보자. 'npm install body-parser --save' 를 cmd에 입력하여 설치한다. 설치가 끝나면 아래의 api에 있는 코드를 통해 우리가 사용하고자 하는 곳에 붙여 넣고, 아래의 examples를 통해 다음의 코드 또한 추가해준다.

var bodyParser = require('body-parser'); //body-parser를 이용하기 위해 추가

app.use(bodyParser.urlencoded({ extended: false })) //bodyparser가 만들어내는 미들웨어를 표현하는 표현식을 추가해준다.
//main.js가 실행될때마다 bodyParser.urlencoded({ extended: false }) 부분에 의해 만들어진 미들웨어가 실행된다. 이는 사용자가 전송한 post 데이터를 내부적으로 분석하여 경로의 콜백부분을 호출하도록 되어있다.
  • body-parser를 안 이용한 코드 (이전 코드로 예시)
app.post('/create_process', function (request, response) { //생성된 데이터를 받아서 그 데이터를 처리하는 코드 이때 데이터는 post방식으로 전달되는데, 이는 데이터의 크기가 get 방식과는 다르게 클 수 있다.
  var body = ''; //그렇기 때문에 body 변수를 정의하고
  request.on('data', function (data) { //data가 추가될 때 마다 req.on data라는 이벤트가 호출되는데
    body += data; //그때마다 기존의 바디 변수값에 데이터가 도착할 때마다 끝에 데이터를 계속 추가해주는 방식.
  });
  request.on('end', function () { //그러다 더이상 데이터가 없다는 이벤트가 발생했을 때 실제 처리해주는 코드를 통해 실행시킨다.
    var post = qs.parse(body);
    var title = post.title;
    var description = post.description;
    fs.writeFile(`data/${title}`, description, 'utf8', function (err) {
      response.redirect(`/page/${title}`);
    });
  });
})
  • body-parser를 이용한 코드
app.post('/create_process', function (request, response) { //우리가 request라 정의한 첫번째 인자에 body라는 프로퍼티가 없었는데, 미들웨어가 그걸 만들어준다.
  var post = request.body; //위의 코드를 이렇게 수정해주면 끝. + 이와 같은 아래의 코드들 또한 전부 수정해준다. (과정은 안 올림)
  var title = post.title;
  var description = post.description;
  fs.writeFile(`data/${title}`, description, 'utf8', function (err) {
    response.redirect(`/page/${title}`);
  }); //bodyparser라는 미들웨어를 장착하니, 내부적으로 동작하여 create_process라는 라우터를 사용할 때 request 객체의 body 프로퍼티에 접근하여 간결하게 코드를 만들 수 있다.
}) //잘 실행되는 것을 확인할 수 있다.

 

훨씬 간편하게 코드를 작성할 수 있고, 발생할 수 있는 여러 문제들을 이 소프트웨어가 대신 해결해준다.

 

-2. compression : 웹 서버가 웹 브라우저한테 응답할 때 데이터를 압축한다.

expressjs.com/en/resources/middleware/compression.html 를 통해 'npm install compression --save'를 cmd에 입력하여 설치한다. api에 적힌 코드를 사용할 코드 안에 넣어주고, 아래의 examples를 통해 다음의 코드 또한 추가해준다.

var compression = require('compression') // add

app.use(compression()) // 함수 compression을 호출하면 미들웨어를 리턴하도록 하여 qpp.use를 통해 장착된다.
  • 압축하기 전 데이터의 사이즈

  • 압축 후 데이터의 사이즈

데이터의 양이 많고 접속 사용자가 많다면, 이러한 작업이 얼마나 큰 장점을 갖게 되는지 알 수 있다.

 

+ tip) 우리가 사용하는 http://localhost:3000의 검사(F12)를 이용할 때 상태(status)가 200이 아닌 304로 뜰 수 있다. 이때 해결 방법은 아래의 '더보기'에 있다.

더보기

304 Not Modified 이건 캐시를 목적으로 사용. 클라이언트에게 응답이 수정되지 않았음을 알려주고, 클라이언트는 계속해서 응답의 캐시 된 버전을 사용할 수 있다. 이의 해결 방법은 생각보다 간단하다.

 

Clear browsing data. Clearing your browsing data will make sure your cache is cleared so it can try to access the URL you're requesting. = 즉 간단히 말해 브라우저의 캐시를 정리해주면 된다. 😁

 

그리고 다시 새로고침을 한다면 상태가 200으로 변경된 것을 볼 수 있다.

 

-3. 미들웨어 만들어보기

expressjs.com/en/guide/writing-middleware.html 를 참고하면 밑의 코드가 있다. (사이트에서 복붙 한 것)

var myLogger = function (req, res, next) {
  console.log('LOGGED')
  next()
} // 이런 형식을 가지고 있는 함수를 미들웨어라고 함. 이 함수 내부를 어떻게 구현하냐에 따라서 이전에 살펴본 서드파티와 같은 기능성을 갖게 된다.
  • 미들웨어를 이용하여 코드를 간편하게 하기
app.get('*', function (request, response, next) { //겹치는 부분에 대한 미들웨어 만들기 + 이때 use가 아닌 get을 이용하는 이유는, 안 읽히는 부분(post 방식)에 대해 이 코드가 불필요하기 때문이다. 그리고 '*'는 모든 요청이란 뜻인데, get방식으로 들어오는 요청에 대해서만 파일 목록을 가져오게 한 것이다.
  fs.readdir('./data', function (err, filelist) { //겹치는 부분 복붙 및 추가 코드 작성 (기존에 이 코드 부분은 제거해준다.)
    request.list = filelist;
    next(); //세번째 인자를 실행시키게 되면, next라는 변수에 다음에 호출되어야 할 미들웨어가 담겨있고 이것이 실행된다.
  })
});

app.get('/', function (request, response) {
  var title = 'Welcome';
  var description = 'Hello, Node.js';
  var list = template.list(request.list); //fs.readdir을 위에 만든 미들웨어에 추가해줬으니, 이 부분의 filelist에는 request.list를 넣는다. (이하 비슷한 코드 전부 수정 작업을 해준다)
  var html = template.html(title, list,
    `<h2>${title}</h2>${description}`,
    `<a href="/create">create</a>`);
  response.send(html);
});

이를 통해 우리는 콜백 부분이 express에서는 미들웨어에 속한다는 것을 알 수 있다. (순서대로 실행되고 있는 것)

 

-4. 미들웨어의 실행순서

expressjs.com/en/guide/using-middleware.html 를 참고. 우리가 지금까지 사용했던 미들웨어는 Application-level middleware라고 한다. 이는 app 변수 안의 객체 use, get, post 등을 통해 미들웨어를 등록할 수 있는데, 이렇게 등록된 미들웨어를 말한다. Application-level middleware는 미들웨어 중 젤 중요!

 

  • 아래는 사이트 내의 예제 코드를 가지고 와서 설명한 것. [순서 설명]
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')
}) //이 코드에서 next를 통해 다음 미들웨어를 호출하지 않았으므로, 여기서 요청이 멈춘다.

// handler for the /user/:id path, which prints the user ID
app.get('/user/:id', function (req, res, next) {
  res.end(req.params.id)
})
app.get('/user/:id', function (req, res, next) {
  // if the user ID is 0, skip to the next route - 1. 만약 값이 0이면 다음 라우트를 실행시켜라.
  if (req.params.id === '0') next('route')
  // otherwise pass the control to the next middleware function in this stack
  else next() //3. 아니라면 그냥 이어서 바로 밑의
}, function (req, res, next) { //4. 이 미들웨어가 실행.
  // 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) { //2. 즉 여기가 실행되는 것.
  res.send('special')
})
Comments