node express 에 대한 개념 설명과 개념을 정리 해보겠다.
1. 미들웨어 스택
express 서버 코드의 핵심은 클라이언트의 각 요청을 처리하는 라우팅 로직을 구현하는것이고, 라우팅 로직을 구현하는 것은 곧 미들웨어 스택을 구출을 의미한다. 미들웨어 스택은 클라이언트의 요청을 처리하는 함수들이 설정된 순서대로 저장되어있는 구조를 의미한다. 이는 미들웨어, 라우터 핸들러, 에러 핸들러로 구성되어있다. 라우터라는 단위로 묶을 수 있다.
1. 애플리케이션 레벨 미들웨어
애플리케이션 레벨이란 아래서 살펴볼 express()로 생성할 수 있는 app 객체의 app.use()나 app.METHOD()(ex. app.get, app.post) 함수를 이용해 미들웨어를 app 인스턴스에 바인딩하는 미들웨어이다. 마운트 경로가 없는 미들웨어 함수는 앱이 요청을 수신할 때마다 실행하게 된다.
app.get('/pages/', (req, res, next) => {
console.log('Time : ', Date.now());
next();
});
app.get((req, res, next) => {
console.log('Not Found');
});
하나의 경로에 app 메서드 여러개가 묶일 수 있는데 다음예시를 주의깊게 보자
app.get('/pages/:id', (req, res, next) => {
if (req.params.id == 0) next('route');
else next();
}, (req, res, next) => {
res.send('regular');
}
});
app.get('/pages/:id', (req, res, next) => {
res.send('special');
}
위에 경우는 2개묶인 app 메서드가 위에 있으므로 special 보다 먼저 실행된다. next() 는 지금 라우터 미들웨어 스택을 벗어난 다음 라우터로 제어가 넘어가게 하는것이다. 라우터 미들워ㅔ어 스택이란 하나의 app.use()나 app.메서드 에 묵인 라우팅 미들웨어들을 말한다.
여기서 그냥 next()는 regular로 넘어가게 된다. id가 0이 아니라서 regular로 넘어간다면, 거기서 next()를 호출하지 않았으므로 special은 호출되지 않는다.
next() 안에 인자가 들어가는 경우는 아마 next('route')와 next(err)뿐일 것 같다. next 안에 뭔가 인자가 들어가면 express 앱은 그것을 오류 발생이라고 보고 오류 처리와 관련없는 다른 모든 미들웨어를 다 건너뛰고 오류 처리(error handling) 라우터로 넘어간다. 단 하나 'route'만 빼고 말이다. 'route'는 현재 메소드를 벗어나 path에 해당하는 다음 라우터로 제어가 넘어가는 것이다.
2. 라우터 레벨 미들웨어
라우터 레벨은 express.Router()로 생성할 수 있는 router 인스턴스에 미들웨어가 바인딩되는 것이다. 그것 외에는 애플리케이션 레벨 미들웨어가 차이가 없다. router.use()나 router.METHOD() 함수를 이용해 로드할 수 있다.
express.Router() 로 router 객체를 생성할 수 있는데, 미들웨어와 HTTP 메소드 라우트를 router 객체에 붙일 수 있다.
//app.js
const express = require('express');
const app = express();
const pageRouter = ('./routes/pages');
app.use('/pages', pageRouter);
//pages.js
const express = require('express');
const router = express.Router();
router.get('/pages/:id', (req, res, next) => {
//pages id가 0이면 'regular'가 아닌 'special'로 넘어감
if (req.params.id == 0) next('route');
//pages id가 0이 아니라면 'regular'로 넘어감
else next();
}, (req, res, next) => {
res.send('regular');
}
});
//pages id가 0일 때 넘어올 미들웨어
router.get('/pages/:id', (req, res, next) => {
res.send('special');
}
module.exports = router;
3. 오류 처리 미들웨어
오류 처리 미들웨어는 (err, req, res, next)를 인자로 받는 것이다. 항상 4개의 매개변수가 필요하다. 이게 오류 처리 미들웨어의 시그니처다. err.stack으로 에러 메시지를 볼 수 있다.
//오류의 종류에 상관없이 모든 오류를 잡는 미들웨어
app.get((err, req, res, next) => {
console.log(err.stack);
res.status(500).send('Something broke!');
});
주의할 점은 오류 처리 미들웨어는 app.use() 및 라우트 호출을 정의한 뒤 거의 코드의 맨 끝에 정의해야 한다는 점이다.
위의 경우 모든 오류를 잡는 미들웨어 하나만 만들었는데, 에러마다 다른 오류 처리 미들웨어 함수를 정의할 수도 있다. 이 경우 catch-all 에러 핸들러는 그 오류 처리 미들웨어들 중에서도 가장 아래 있어야 한다.
오류 처리 미들웨어는 다음과 같이 부를 수 있다.
4. 기본 제공 미들웨어
기본 제공은 정적 리소스를 제공할 루트 디렉토리를 정하는 express.static 같은 것이 있다. 현재 문서에는 빌트인 미들웨어는 express.static 뿐이라고 되어 있다. 정적 파일을 전달해주는데, 여기서는 /public 디렉토리가 정적 파일들이 모여 있는 루트 디렉토리가 된다. 아래서 더 자세히 설명하겠다.
app.use(express.static(__dirname + '/public'));
5. 써드파티 미들웨어
마지막으로 써드파티 미들웨어는 npm 에서 설치한 helmet이나 cookie-parser 같은 모듈들이 해당이 된다. 쉽게 말해 express 자체적으로 제공하지 않고 따로 설치해야 하는 것들은 다 써드파티라고 보면 된다.
npm i cookie-parser
const express = require('express');
const app = express();
const cookieParser = require('cookie-parser');
app.use(cookieParser());
이 때 cookieParser()를 하면 미들웨어를 반환한다.
'react > 리액트 + Express' 카테고리의 다른 글
리액트 csr + Tailwind css 프로젝트 생성(사용) (0) | 2023.12.22 |
---|---|
리액트 성능최적화 (0) | 2023.12.17 |
(Clean Architecture)클린 아키텍처 - feat(React) (0) | 2023.12.12 |
리액트 + Express + Mysql 연동 테이블 값 뿌리기 (6) | 2022.12.29 |
리액트 express 를 사용하여 MySQL 연동하기 (4) | 2022.12.28 |