본문 바로가기
Programming

[Node.js] Express 미들웨어 함수

by 개발자 염상진 2022. 5. 26.

 

 

미들웨어(Middleware) 함수

 

Express는 자체적인 최소한의 기능을 가진 라우팅 및 미들웨어 웹 프레임워크다. Express 애플리케이션은 일련의 미들웨어 함수를 호출한다. 

 

미들웨어 함수란 요청 오브젝트(req)와 응답 오브젝트(res) 그리고 애플리케이션의 요청-응답 주기 중 다음 미들웨어 함수에 대한 액세스 권한을 가지는 함수다. express내에서 미들웨어 함수는 next()로 표시된다.

 

현재 미들웨어 함수가 요청-응답 주기를 종료하지 않는 경우 next()를 호출하여 다음 미들웨어 함수에 제어를 전달해야 한다. 만약 다음 next() 미들웨어 함수로 제어권을 전달하지 않는 경우 요청은 정지된 채로 아무것도 하지 않게 된다. 

 

미들웨어 함수 구조

 

미들웨어는 프로세스 중간에 관여해 특정 역할을 수행하게 된다. express에서는 수많은 미들웨어 함수가 존재하기 때문에 필요할 때 마다 필요한 미들웨어 함수를 적용해 서버를 구성할 수 있다. 미들웨어의 일반적인 구성은 아래 그림과 같다.

 

미들웨어 일반적인 구성(출처 : express 공식 홈페이지)

 

 

간단한 미들웨어 함수 작성하기

 

미들웨어 함수 중 가장 간단한 LOGGER 미들웨어는 현재 상황을 출력하는 기능외에 아무런 기능을 수행하지 않는다. 모든 요청이 들어오는 경우에  LOGGER 미들웨어가 실행되도록 app 인스턴스에 바인딩시킨다.

 

주의할 점은 LOGGER 미들웨어 함수에서 next() 함수를 호출하면서 다음 미들웨어에 제어권을 넘겨주고 있다는 사실이다. 만약 next() 함수를 호출하지 않으면 서버가 멈춰버린다.

// Logger 미들웨어 함수
const myLogger = function(req, res, next){
    const {method, url}  = req;
    console.
    log(`http request method is ${method}, url is ${url}`);
    // next();
}

// Logger 미들웨어 로드
// 모든 요청에 대해 Logger 미들웨어 실행됨
app.use(myLogger);

// 모든 요청에 대해 응답 진행
app.use('/', (req, res)=>{
    res.send("This is the Express Server!");
})

 

next() 함수 제거한 경우

여기서 서버가 멈춰버림. 다음 제어권을 받을 함수를 찾지 못하기 때문

 

 

미들웨어 함수가 할 수 있는 것?

  • 모든 코드 실행
  • 요청 및 응답 오브젝트에 대한 변경 실행
  • 요청-응답 주기 종료
  • 스택 내 다음 미들웨어 함수 호출 가능

 

미들웨어를 사용하는 상황

  • 모든 요청에 대해 url이나 메소드를 확인 하는 경우
  • POST 요청 등에 포함된 body(payload로 전달)를 구조화 하는 경우
  • 모든 요청/응답에 CORS 헤더를 붙이는 경우
  • 요청 헤더에 사용자 인증 정보가 담겨있는지 확인하는 경우

 

 

애플리케이션 레벨 미들웨어

 

애플리케이션 레벨 미들웨어 함수는 선택적인 마운트 경로를 통해 로드가 가능하다. 일련의 미들웨어 함수를 함께 로드할 수도 있다. 여러개의 미들웨어 함수를 하나의 마운트 위치 지정하고 미들웨어 시스템의 하위 스택을 생성할 수 있다.

 

app.use()이나 app.put(), app.get()등 HTTP 메소드를 app 인스턴스에 바인드해서 사용할 수 있다. 마운트 경로가 없는 미들웨어 함수는 앱이 요청을 수신할 때 마다 실행된다.

 

app.use() 미들웨어 함수에서 마운트가 /data/:id 로 지정된 경우 모든 HTTP 메소드에서 실행된다.

const app = express();

app.use((req, res)=>{
	console.log("Time : ", Date.now());
    next();
})

app.use('/data/:id', (req, res)=>{
	console.log('Request Method : ', req.method);
    next();
})

 

하나의 마운트 경로에 대해 일련의 미들웨어 함수를 위치시킬 수 있다. 일련의 미들웨어 함수는 하위 스택을 생성하게 된다.

 

app.use('/', (req, res, next)=>{
    console.log(`resquest : ${req.originalUrl}`)
    next();
},(req, res, next)=>{
    console.log(`request type : ${req.method}`)
    res.send("this is the second function")
})

 

 

 

라우터 레벨 미들웨어

 

라우터 레벨 미들웨어는 express 인스턴스에 바인딩 되지 않고 express.Router() 인스턴스에 바인딩된다. 나머지 기능은 애플리케이션 레벨 미들웨어와 동일한 방식으로 작동한다.

 

const router = express.Router();

 

router.use(), router.METHOD()를 사용해서 라우터 레벨 미들웨어를 로드할 수 있다. 미들웨어에 마운트 지점이 지정되지 않은 경우 모든 요청에 대해 미들웨어 함수가 실행된다.

 

const app = express();
const router = express.Router();

router.use(function (req, res, next) {
  console.log('Time:', Date.now());
  next();
});

router.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();
});

 

 

CORS 미들웨어 함수 사용

 

순수 Node.js에서 CORS 헤더를 붙이기 위해서는 응답 객체의 whiteHead를 사용한다. 매번 Access-Control-Allow-* 헤더를 정의해줘야 한다. 또한 preflight를 위한 라우팅 코드도 구현해줘야 한다. 

 

const basic_CORS_Headers = {
	'Access-Control-Allow-Origin' : '*',
    'Access-Control-Allow-Method' : 'GET, POST, PUT, DELETE, OPTIONS',
    'Access-Control-Allow-Headers' : 'Content-Type, Accept', 
    'Access-Control-Max-Age' : 10
}

if(req.method === 'OPTIONS'){
	res.whiteHead(201, basic_CORS_Headers);
    res.end();
}

 

 

express의 CORS 미들웨어 함수를 사용하면 위 과정을 간략하게 바꿀 수 있다.

 

const cors = require('cors');

// 애플리케이션 레벨 미들웨어 use()를 통해 cors()를 로드함.
// 모든 요청에 CORS를 허용함.
app.use(cors());

// 마운트를 지정해서 특정 메소드에 대해 CORS 적용
app.get('/test/:id', cors(), (req, res)=>{
	res.json("This is about CORS");
})

 

 

Reference

 

 

 

 

[Web Server] Express Routing query VS params

Express Routing 라우팅은 URI(또는 경로) 및 특정 HTTP 요청 메소드(GET, PUT, POST, DELETE 등)인 특정 엔드포인트에 대한 클라이언트 요청에 애플리케이션이 응답하는 방식이다. 즉, 클라이언트가 특정 HTTP.

about-tech.tistory.com

 

 

[React] Effect HOOK API useEffect 사용하는 방법

React 데이터 흐름? React 데이터 흐름 React의 개발 방식의 가장 큰 특징은 컴포넌트 단위로 페이지를 구성하는 것이다. 한개의 웹 페이지를 여러 컴포넌트로 잘라서 구성한 뒤 조립하는 형식으로

about-tech.tistory.com

 

 

[Programming] CORS란? (preflight, OPTIONS 메소드?)

CORS가 도입된 배경 CORS가 도입되기 전 클라이언트들은 서버에서 제공하는 리소스를 가지고만 서버와 통신을 진행했다. 이 경우 서버와 클라이언트의 origin은 동일했기 때문에 굳이 CORS를 도입하

about-tech.tistory.com

 

댓글