express middleware

carrot·2021년 7월 24일
0

Express

자체적인 최소한의 기능을 갖춘 라우팅 및 미들웨어 웹 프레임워크. express 애플리케이션은 기본적으로 일련의 미들웨어 함수 호출입니다.

middleware

미들웨어 함수는 request(요청 오브젝트), response(응답 오브젝트), 그리고 애플리케이션의 요청-응답 주기 중 그 다음의 미들웨어 함수에 대한 엑세스 권한을 갖는 함수입니다.
그 다음의 미들웨어 함수는 일반적으로 next라는 이름의 변수로 표시됩니다.

middleware 함수로 할 수 있는 것

  1. 모든 코드를 실행합니다.
  2. 요청 및 응답 오브젝트에 대한 변경을 실행합니다.
  3. 요청-응답 주기를 종료합니다.
  4. 스택 내의 그 다음 미들웨어 함수를 호출합니다.(next)

현재의 미들웨어 함수가 요청-응답 주기를 종료하지 않는다면 해당 요청은 정지된 채로 방치됩니다. 이를 해결하기 위해서는 반드시 next()함수를 호출하여 다음 미들웨어로 제어를 전달해야 합니다.

middleware 예제

GET request를 처리하는 간단한 예제를 살펴보겠습니다.

const app = express();

app.get('/user/:id', function(req, res, next){
    console.log('Request Type: ', req.method);
    next();
  },
  function(req, res){
  	res.send('User Request DONE.')
  }
);

위 함수는 'user/:id' 경로에 마운트 되는 미들웨어 함수가 2개 있습니다.
경로 뒤의 function이 바로 미들웨어 함수 입니다.

첫 번째 미들웨어 함수는 request 요청의 method 값을 콘솔창에 출력하고 next() 함수를 호출하여 제어권을 다음 미들웨어 함수에게 넘깁니다.

두 번째 미들웨어 함수는 제어권을 넘겨 받은 후 'User Request DONE.' 이라는 텍스트 메시지를 response 하며 요청에 대한 응답을 종료합니다.

middleware 적용 사례

클라이언트에서 프로젝트 모집 글에 지원을 하는 사례를 예로 들어 보겠습니다.
request에 포함된 프로젝트 ID값을 통해 MongoDB에서 해당 프로젝트를 찾고 프로젝트의 volunteer 배열 값에 지원한 유저의 ID값을 저장하고 업데이트된 프로젝트 정보를 response 하는 구조입니다.

router.post("/apply", projectFindOne, (req, res) => {
  Project.findOneAndUpdate(
    { _id: req.body.classId },
    { volunteer: req.project.volunteer.concat(req.body.userId) },
    { new: true },
    (err, updatedProject) => {
      if (err) return res.json(findOneError(PROJECT_MODEL, err));
      if (!updatedProject)
        return res.json(notFoundError(PROJECT_MODEL, req.body.classId));

      return res.status(200).json(projectUpdateSuccess(updatedProject));
    }
  );
});

/apply로 들어온 post 요청을 두 개의 미들웨어가 처리하고 있습니다.
projectFindOne 미들웨어에서는 req.body.classId 값을 통해 MongoDB에서 해당 프로젝트를 찾아 req.project라는 변수에 담아 다음 미들웨어로 전달해 주는 역할을 하고 있습니다.

projectFindOne은 다음과 같이 작성하였습니다.

let projectFindOne = (req, res, next) => {
  Project.findOne({ _id: req.body.classId }, (err, project) => {
    if (err) return res.json(findOneError(PROJECT_MODEL, err));
    if (!project)
      return res.json(notFoundError(PROJECT_MODEL, req.body.classId));

    req.project = project;
    next();
  });
};

위 미들웨어는 request 오브젝트에 대한 변경을 실행하고 있습니다. 최초 request 요청에는 없었던 project를 찾아 req.project에 추가하고 있는 것이 그것입니다. 이후 응답을 종료하지 않고 next()를 통해 다음 미들웨어 함수를 호출하고 있습니다.

middleware를 통해 얻을 수 있는 것

요청에 대한 응답코드를 작성하다 보면 중복되는 기능들이 자주 발생합니다. 유저가 프로젝트에 지원을 하는 것, 또는 지원을 취소하는 것, 프로젝트를 생성한 유저가 요청을 수락하거나 거절하는 것 등 이 기능들은 모두 DB에 저장된 해당 프로젝트 정보를 찾는 것을 포함하고 있습니다.

이렇게 중복이 발생되는 부분을 미들웨어 함수로 모듈화 하고 필요한 요청에서 사용한다면 코드를 간소화 할 수 있고 가독성이 높아집니다. 디버깅 또한 간편해집니다. 해당 미들웨어에서 발생하는 err처리를 하고 있기 때문이죠.

response 코드가 지저분하고 중복된 코드가 많이 발견된다면 미들웨어를 통해 코드를 정리해 보는 것을 추천드립니다.

profile
당근같은사람

0개의 댓글