express 프레임워크를 공부하며 middleware라는 용어는 여전히 잡힐듯 잡히지 않는 개념이다.
추상적으로 클라이언트, 서버 사이에서 데이터를 주고 받는 '무언가'라고만 알고 그저 코드를 작성하고 있는 상황. 이렇게 토대가 빈약한 지금이라도 정리를 미리미리 하자는 취지에서 하는 정리!
미들웨어라는 개념은 express 이외에도 여러 시스템에서 사용되기 때문에, 현재 공부하고 있는 express 프레임워크를 기반으로 미들웨어의 개념을 잡아보도록 하자!
위키백과의 정의에 따르면 미들웨어란,
운영 체제와 응용 소프트웨어의 중간에서 조정과 중개의 역할을 수행하는 소프트웨어이다. 응용 소프트웨어가 운영 체제로부터 제공받는 서비스 이외에 추가적으로 이용할 수 있는 서비스를 제공하는 컴퓨터 소프트웨어이다. "소프트웨어 글루"(software glue)로 이야기된다.
express 공식 홈페이지에 따르면, 미들웨어는 요청 / 응답 객체를 변경하고, 다음 미들웨어 함수를 next()를 통해 호출할 수 있다.
express 프레임워크로 크게 다섯 가지 유형의 미들웨어를 사용할 수 있다.
어플리케이션 레벨에선 app이라는 변수에 담아 구현한다.
const express = require('express')
const app = express()
app.use('/path', (req, res, next) => {
....
next()
});
클라이언트가 첫 번째 인자로 갖고 있는 엔드포인트에 요청을 보내면 그에 맞는 함수를 구현해 응답하는 방식이다.
app의 하위 객체로는 use 이외에도 http 메서드를 사용해 구현할 수 있다.
라우터 레벨에선 express 내 Router() 객체를 router라는 변수에 담아 새로운 router 객체를 생성할 수 있도록 한다. 이외의 기능은 어플리케이션 레벨과 비슷하다.
const express = require('express')
const app = express()
const router = express.Router()
router.use((req, res, next) => {
if (!req.headers['x-auth']) return next('router')
next()
})
router.get('/user/:id', (req, res) => {
res.send('hello, user!')
})
app.use('/admin', router, (req, res) => {
res.sendStatus(401)
})
라우터 전체를 관장하기 위해서 app.use를 마지막 단에 사용한다.
app.use 가운데 router를 미들웨어로 넣어 위에 구현한 router 함수를 사용할 수 있다.
에러핸들링 미들웨어는 항상 4개의 인수를 취한다.
app.use((err, req, res, next) => {
console.error(err.stack)
res.status(500).send('Something broke!')
})
첫 번째 인자로 err를 받아 에러를 처리할 수 있도록 한다.
express에는 다음과 같은 미들웨어 기능이 내장되어 있다.
express.static은 HTML 파일, 이미지 등과 같은 정적 자산을 제공합니다.
express.json은 JSON payload로 들어오는 요청을 분석합니다.
express.urlencoded는 URL 인코딩 payload로 들어오는 요청을 구문 분석합니다.
다른 개발자가 만들어 놓은 미들웨어를 사용하기 위해선 npm install을 통해 설치 후 해당 파일을 require 하여 사용할 수 있다.
현재 typeorm 등의 써드 파티 모듈을 사용하고 있다.