Node.js - Express.js (middleware)

ryan·2022년 5월 12일
0

middleware

  • express.js동작의 핵심. http 요청과 응답 사이에서 단계별 동작을 수행해주는 함수
  • express.js의 미들웨어는 http 요청이 들어온 순간부터 시작됨
  • 미들웨어는 http 요청과 응답 객체를 처리하거나 다음 미들웨어를 실행할 수 있음
  • http 응답이 마무리될 때까지 미들웨어 동작 사이클이 실행됨
  • middleware는 기본적으로 req ,res,next 3개의 매개변수를 가짐

Router Handler

  • Router Handler는 라우팅 함수(get,post,put,delete 등)에 적용된 미들웨어.
  • 일반적인 미들웨어와는 다르게 path parameter를 사용할 수 있음.
const logger = (req,res,next)=>{
    console.log(`Request ${req.path}`);
    next();
} // next를 사용하지 않으면 middleware가 끊기므로 주의
const auth = (req,res,next)=>{
    if(!isAdmin(req)){
        res.send('not authorized');
        return;
    }
    next();

}

  • middleware는 적용되는 위치에 따라
  • 어플리케이션 미들웨어 라우터 미들웨어 오류처리 미들웨어로 분류가능
  • 필요한 동작 방식에 따라 미들웨어를 적용할 위치를 결정

애플리케이션 미들웨어

  • app객체에 use를 통해서 연결하거나 app객체에 http method함수를 사용하여 미들웨어를 연결하면 애플리케이션 미들웨어라고 할 수 있음
  • 미들웨어를 모든 요청에 공통적으로 적용하기 위한 방법
  • http 요청이 들어온 순간부터 적용된 순서대로 동작함
app.use((req,res,next)=>{
    console.log(`${req.path}`);
    next();
})
app.use(auth);
app.get('/',(req,res,next)=>{
    res.send('heelo express');
})

라우터 미들웨어

  • router 객체에 미들웨어가 적용되는 것 외에는 애플리케이션 미들웨어와 동일
    특정 경로의 라우팅에만 미들웨어를 적용하기 위한 방법
  • app 객체에 라우터가 적용 된 이후로 순서대로 동작함
router.use(auth); //3

router.get('/',(req,res,next)=>{
    res.send('hello router');
}) //4

app.use((req,res,next)=>{
    console.log(`${req.path}`);
    next();
}) // 1
app.use('/admin',router) // 2

미들웨어 서브스택

  • use나 http method 함수에 여러 개의 미들웨어를 동시에 적용할 수 있음
  • 주로 한개의 경로에 특정해서 미들웨어를 적용하기 위해 사용
  • 전달된 인자의 순서 순으로 동작
app.use(middleware1,middleware2); // 순서대로 동작
app.use('/admin',auth,adminRouter); // 순서대로 동작

오류처리 미들웨어

  • 오류처리 미들웨어는 일반적으로 가장 마지막에 위치를
  • 다른 미들 웨어들과는 달리 err,req,res,next 네가지 인자를 가지며,
  • 앞의 미들웨어에서 next 함수에 인자가 전달되면 실행됨
app.use((req,res,next)=?{
    if(!isAdmin(req)){
        next(new Error('not authorized')); // 1. 에러 발생시킴
        return;
    }
    next();
})

app.get('/',(req,res,next)){ // 3. 여기 미들웨어는 실행되지 않음
    res.send('nothing')
}

app.use((err,req,res,next)=>{ // 2.바로 여기로 전달됨
    res.send('error!!!') 
})

함수형 미들웨어

  • 하나의 미들웨어를 작성하고, 작동 모드를 선택하면서 사용하고 싶을 경우
  • 미들웨어를 함수형으로 작성하여 사용할 수 있음
  • API 별로 사용자의 권한을 다르게 제한하고 싶은 경우
  • 모듈을 함수형으로 작성한 것과 유사함
  • 일반적으로 동일한 로직에 설정값만 다르게 미들웨어를 사용하고 싶을 경우 해당됨
auth 함수 실행 시 미들웨어의 동작이 결정되는 방식으로 저장됨
const auth = (memberType)=>{
    return (req,res,next)=>{
        if(!checkMember(req,memberType)){
            next(new Error(`member not ${memberType}`));
            return;
        }
        next();
    }
}

app.use('/admin',auth('admin'),adminRouter);
app.use('/admin',auth('member'),userRouter);

middleware library

  • 다양한 미들웨어들이 이미 만들어져 라이브러리로 제공됨
  • cors.multer,passport 등

예제

app.use((req, res, next) => {
  // app 객체 내부 함수는 미들웨어, use는 모든 요청에 실행하고 싶을 때 사용
  console.log('모든 요청에 실행');
  next();
});
////

app.use('/about', (req, res, next) => {
  // use에 주소를 붙이면 about에서만 실행됨
  console.log('모든 요청에 실행');
  next();
});
////

app.use(
  // app 객체 하나에 여러개의 미들웨어가 있어도 됨
  (req, res, next) => {
    console.log('모든 요청에 실행');
    next();
  },
  (req, res, next) => {
    console.log('모든 요청에 실행');
    next();
  },
  (req, res, next) => {
    console.log('모든 요청에 실행');
    next();
  }
);
////

app.use((req, res, next) => {
  // 기본적으로 상태코드 200 생략되어 있음
  res.status(200).send('hi');
});
////

app.get('/', (req, res) => {
  // 한 요청(이전 미들웨어도 포함)에 에서 두 번이상 response하면 에러나옴
  res.sendFile(path.join(__dirname, 'index.html'));
  res.json();
  res.send('hi');
});
////

app.get('/', (req, res) => {
  // 기존 http에서는 아래와 같이 표기
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.end('hi');

  // express에서는 header도 더 간편하게 표기
  res.setHeader('Content-Type', 'text/html');
  // express에서는 http의 두 줄을 아래 한 줄로 표기
  res.status(200).send('안녕하세요'); //status 생략가능
});

server 순서

  • app과 관련된 세팅
  • 공통 적용하는 미들웨어 세팅
  • 라우터 세팅(범위가 넓을수록 아래쪽)
  • 에러 미들웨어
profile
프론트엔드 개발자

0개의 댓글