song.log

[Node.js] Express : 미들웨어(Middleware) 만들기, 실행 순서, 사용법 본문

DevLog/Node.js

[Node.js] Express : 미들웨어(Middleware) 만들기, 실행 순서, 사용법

SingaKorean 2019. 12. 23. 22:54
반응형

1. Middleware 만들기

코드를 짤 때, 공통적으로 사용되는 부분이 겹칠 때, 그 함수를 middleware로 만들어서 사용하는 것이 가능하다.

middleware의 형태는 다음과 같다. 

 

여태까지 짠 main.js파일에서는 폴더 내의 파일 리스트를 읽는 작업을 반복적으로 했는데, 그 부분을 middleware로 만들어서 활용하는 것이 가능하다. 

app.use(function(request, response, next){
  fs.readdir('./data', function(error, filelist){
    request.list = filelist;
    next();
  })
});

 

<기존 코드>

app.get('/', function(request, response) { 
  fs.readdir('./data', function(error, filelist){
    var title = 'Welcome';
    var description = 'Hello, Node.js';
    var list = template.list(filelist);
    var html = template.HTML(title, list,
      `<h2>${title}</h2>${description}`,
      `<a href="/create">create</a>`
    ); 
    response.send(html);
  });
});

 

<새로운 코드>

app.get('/', function(request,response){
  var title = 'Welcome';
  var description = 'Hello, Node.js';
  var list = template.list(request.list);
  var html = template.HTML(title, list,
    `<h2>${title}</h2><p>${description}</p>`,
  `<a href="/create">create</a>`,'');
  response.send(html);
});

하지만 app.use는 이 미들웨어가 개입할 필요가 없는 부분에까지 적용되기 때문에, 불필요한 개입이 없기 위해서 get/post 방식으로 나누어서 적용시키는 방법도 있다. 

 

get 방식으로 요청을 하는 부분에 모두 적용 시키기 위해서 아래와 같이 코드를 작성한다. 

app.get('*',function(request, response, next){
  fs.readdir('./data', function(error, filelist){
    request.list = filelist;
    next();
  })
});

 

2. Middleware의 실행순서 / 사용법

- 경로를 설정해서 적용시킬 수 있다.

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()
})

 

- 같은 경로에 다른 미들웨어를 적용시킬 수 있다. 하지만 아래의 코드의 경우 res.send()에서 끝나고 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.end(req.params.id)
})

 

- 조건문을 통해서 그 다음 미들웨어를 적용시킬 수 있다. 

next('route')일 경우 그 다음으로 오는 인자가 아닌, 따로 적은 미들웨어가 적용되고, 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')
})

 

3. 정적인 파일의 서비스

웹페이지에 정적인 파일(images, css, javascript)등을 웹브라우저로 다운로드 받게끔 하는 서비스를 해보고자 한다. 

먼저 정적인 파일의 서비스를 허용시키기 위한 코드는 아래와 같다. 

app.use(express.static('public'));

public/images/hello.jpg 라는 경로로 저장한 이미지 파일은 http://localhost:3000/images/hello.jpg 로도 웹브라우저에서 볼 수 있다는 점을 활용하여  html 코드로 보여주고자 하는 웹 페이지에 적용시킨다.

 <img src="/images/hello.jpg" style="width:300px; display:block; margin-top:10px;">

 

4. 에러처리

1). 404 Error

모르는 웹페이지로 넘어가서 404 페이지를 보여주고자 할 때 아래의 미들웨어만 추가해주면 된다. 이 때, 이 미들웨어는 순서상 모든 코드를 읽고 실행하기 직전에 위치해야 다른 코드까지 다 살펴본다음에 화면에 뜰 수 있다.

app.use(function(req, res, next) {
  res.status(404).send('Sorry cant find that!');
});

 

2) 에러가 났을 때 나오고자 하는 페이지 설정하는 방법

먼저 콜백함수에 next라는 인자를 추가하고 에러가 났을 경우 err의 미들웨어를 적용하게끔 설정

app.get('/page/:pageid', function(request, response, next){
  
  var filteredId = path.parse(request.params.pageid).base;
  fs.readFile(`data/${filteredId}`, 'utf8', function(err, description){
    if(err){
      next(err);
    }else{
      var title = request.params.pageid;
      var sanitizedTitle = sanitizeHtml(title);
      var sanitizedDescription = sanitizeHtml(description,{
        allowedTags:['h1']
      });
      var list = template.list(request.list);
      var html = template.HTML(sanitizedTitle, list,
        `<h2>${sanitizedTitle}</h2><p>${sanitizedDescription}</p>`,
      `<a href="/create">create</a>  <a href="/update/${sanitizedTitle}">update</a>
      <form action="/delete_process" method="post">
        <input type="hidden" name="id" value="${sanitizedTitle}">
        <input type="submit" value="delete">
      </form>
      `);
  
      response.send(html);
    }
    
  });

});

에러가 났을 때 나왔으면 하는 페이지를 나오게 하는 미들웨어를 아래에 적어줌

app.use(function (err, req, res, next) {
  console.error(err.stack)
  res.status(500).send('Something broke!')
})

 

참조한 생활코딩 URL :

https://opentutorials.org/module/3590/21398

https://opentutorials.org/module/3590/21399

https://opentutorials.org/module/3590/21424

 

 

 

 

반응형
Comments