[express] Middleware

dk.han·2022년 10월 13일
0

Middleware

express는 middleware의 연속이라고 할 수 있다. 즉 여러개의 미들웨어가 체이닝으로 연결되어 있는 것이다.
서버에 요청이 들어오게 되면 미들웨어를 순서대로 거치게 되므로 설정된 순서가 매우 중요하다.
또한 우리가 작성한 미들웨어에서 next()호출과 response를 적절하게 해줘야 미들웨어 체인이 잘 작동할 수 있다.

  • next()는 다음 미들웨어로 넘어갈 수 있도록 해주고
  • 특정 미들웨어에서 response를 하게 된다면 그 뒤에 있는 미들웨어는 실행되지 않는다.

Error handler를 꼭 등록해 놓자 (에러 안전망)

app.get('/',
  (req, res, next) =>{
  console.log('first');
  next(new Error('error')); // 에러 처리
  },
  (req, res, next) =>{
    console.log('first2');
  }
);

app.use((error, req, res, next) => {
  console.error(error); // 서버에 에러 출력
  res.status(500).send('Sorry, try later') 
  // 사용자에게 보여지는 메세지.
})
app.listen(8080);

중간에 에러가 발생하게 된다면 next()의 인자로 에러를 받아 처리할 수 있다. 하지만 별도의 처리를 하지 않을 경우 에러가 UI를 통해 고스란히 사용자에게 보여지게 된다. 때문에 항상 어플리케이션 마지막에는 에러 핸들러를 등록해주어야 한다. 에러 핸드러를 등록해 놓으면 중간에 에러가 발생해도 에러 핸들러 미들웨어에서 설정한 status code와 메세지로 에러를 처리하여 사용자에게 조금이라도(?) 친절한 메세지를 전달할 수 있다.

클라이언트에서 등록되지 않은 경로로 요청한 경우

미들웨어에서 처리 할 수 없는 다른 경로에 접속하면 cannot GET 이라고 뜨게 된다. 아무것도 처리가 되지 않고 결국 마지막까지 여기에 도달했다는 것은 요청에 대해서 처리하지 않았다는 의미다.

app.use((req, res, next) => {
  res.status(404).send('Not available!')
})

이런식으로 처리함으로써 유저에게 처리 할 수 없는 경로라는 것을 보여주고 알려줄 수 있다.

app.all() vs app.use()

all(), use() 둘 다 모든 http requset methods (post, get, delete...등)에 대해서 코드가 수행된다.

app.all('/api', (req, res, next) => {
  console.log('all');
  next()
})

// /* 이런식으로 쓰게되면 app.use처럼 쓸 수 있다.
app.all('/api/*', (req, res, next) => {
  console.log('all');
  next()
})
app.use('/sky', (req, res, next) => {
  console.log('use');
  next()
})

res.send()를 사용시 주의할 점!

아래와 같이 조건에 맞으면 res.send('Hello')를, 그 외에는 res.send('DK')을 수행하는 코드를 코드가 있다면 이는 에러가 발생한다. 하나의 콜백에서 response를 2번 보내게 되는 상황이기 때문이다. if문의 조건이 맞아 클라이언트에게 response를 보냈는데 같은 콜백함수에서 한번 더 response를 보내는건 안된다.

app.get('/',
  (req, res, next) =>{
  console.log('first');
  if(true) {
    res.send('Hello')
  }
  res.send('DK');
})

때문에 조건에 따른 response를 보내는 경우 return을 붙여주어서 response를 하게 되면 콜백함수를 종료시켜 나올수 있도록 해야한다.

app.get('/',
  (req, res, next) =>{
  console.log('first');
  if(true) {
    return res.send('Hello')
  }
  res.send('DK');
})

Reference

노드로 배우는 백엔드 A-Z

0개의 댓글