미들웨어 특성미들웨어 종류Router 객체로 라우팅 분리하기queryParameter, pathVariabledotenv를 이용한 환경변수 설정req, res 객체 살펴보기에러 처리 미들웨어Typescript로 Express 실행하기
미들웨어 특성
- 미들웨어는 익스프레스의 핵심으로, 요청과 응답의 중간(middle)에 위치하여 미들웨어라고 부름. 라우터와 에러 핸들러 또한 미들웨어의 일종이므로 미들웨어가 익스프레스의 전부라고 해도 과언이 아님
- Spring에서 filter 개념 + Controller logic 이 미들웨어에 포함되어 있다고 생각 가능(요청과 응답의 중간, 그리고 응답으로 어떤 값을 내려줄 지도 정할 수 있으니)
- 미들웨어는 req, res, next를 매개변수로 가지는 함수로서(에러처리 미들웨어만 예외적으로 err, req, res, next를 가짐)
app.use
,app.get
,app.post
등으로 장착함
- 특정한 주소의 요청에만 미들웨어가 실행되게 하려면 첫 번째 인수로 주소를 넣으면 됨
app.use( morgan('dev'), express.static('/', path.join(__dirname, 'public')), express.json(), express.urlencoded({ extended: false }), cookieParser(process.env.COOKIE_SECRET), );
- 미들웨어는 내부적으로 next를 호출하고 있으므로 연달아 쓸 수 있음
- 미들웨어 장착 순서에 따라 어떤 미들웨어는 실행되지 않을 수도 있음(중간에 return 해버리면)
- next도 호출하지 않고 return도 하지 않으면 클라이언트는 응답을 받지 못해 계속 기다리게 됨
- next() ⇒ 다음 미들웨어로
- next(’route’) ⇒ 해당 주소와 일치하는 다음 라우터로
- next(error) ⇒ 에러 핸들러로
- 미들웨어 간에 데이터 전달을 위해서는 req 객체에 데이터를 넣어두면 됨 (세션에 넣어도 되지만 세션이 유지되는 동안 데이터도 계속 유지된다는 단점)
app.set과 req 객체에 데이터 넣는 것의 차이
app.set으로 익스프레스에서 데이터를 저장할 수 있음. app.set은 익스프레스에서 전역적으로 사용되므로 사용자 개개인의 값 넣기에는 부적절함
req 객체는 요청을 보낸 사용자 개개인에게 귀속되므로 req 객체를 통해 개인의 데이터를 전달하는 것이 좋음
미들웨어 종류
- morgan : 요청, 응답에 대한 로그 제공해줌
- static : 정적인 파일들을 제공하는 라우터 역할을 함
- body-parser : 본문에 있는 데이터를 해석해서 req.body 객체로 만들어줌
- 폼 전송은 url encoded 방식을 주로 사용함
- cookie-parser : request 에 들어있는 쿠키를 해석해 req.cookies 객체로 만듬
- name=zerocho ⇒ { name : ‘zerocho’ }
- express-session : 세션 관리용 미들웨어
- multer : 이미지, 동영상 등을 비롯한 여러 가지 파일들을 멀티 파트 형식으로 업로드 할 때 사용하는 미들웨어
express-fileupload
andmulter
are both middleware packages for handling file uploads in Node.js applications with Express.
//적용 방식 app.use(morgan('dev')); // dev 외에 combined, common, short, tiny 등을 넣을 수 있음 app.use('요청 경로', express.static('실제 경로')); app.use('/', express.static(path.join(__dirname, 'public'))); //body-parser는 미들웨어 일부 기능이 express에 내장되어 바로 이용 가능함 app.use(express.json()); app.use(express.urlencoded({ extended: false })); // false면 querystring 모듈, true 면 qs 모듈 app.use(cookieParser(비밀키)); app.use(session({ resave: false, saveUninitialized: false, secret: process.env.COOKIE_SECRET, cookie: { httpOnly: true, secure: false, }, name: 'session-cookie', }));
Router 객체로 라우팅 분리하기
- router 객체는 mini-application으로 생각할 수도 있으며, middleware와 routing function으로서의 역할이 가능함
const express = require('express'); const router = express.Router(); router.get('/', (req, res) => { res.send('Hello, Express'); }); module.exports = router;
const express = require('express'); const router = express.Router(); router.get('/', (req, res) => { res.send('Hello, User'); }); module.exports = router;
const express = require('express'); const path = require('path'); const app = express(); dotenv.config(); const indexRouter = require('./routes'); // index.js는 default여서 따로 지정하지 않아도 됨 const userRouter = require('./routes/user'); app.use('/', indexRouter); app.use('/user', userRouter); app.use((req, res, next) => { res.status(404).send('Not Found'); }); app.use((err, req, res, next) => { ...
- app.js에서 해당 router들을 불러와서 app.use로 연결하면, 주소가 합쳐지게 됨
app.use(’/’, indexRouter)
⇒ / + / = / 경로로 매핑app.use(’/user’, userRouter)
⇒ /user + / = /user 경로로 매핑
queryParameter, pathVariable
router.get('/user/:id', (req, res) => { console.log(req.params, req.query); // req.params 로 pathVaraible 접근 // req.query 로 queryParameter 접근 });
- 이 패턴을 사용하려면 다른 일반 라우터보다 뒤에 위치해야 함
dotenv를 이용한 환경변수 설정
COOKIE_SECRET=cookiesecret
- dotenv 패키지는 .env 파일을 읽어서 process.env로 만듬.
- dotenv.config()를 호출하면 됨
import * as dotenv from 'dotenv'; dotenv.config(); // 이후 process.env.COOKIE_SECRET 으로 접근가능
req, res 객체 살펴보기
- http 모듈의 req, res 객체를 확장한 것으로 원래 http 모듈의 메서드도 사용할 수 있고 res.send, res.sendFile 같은 메서드도 사용할 수 있음
req 객체 [ 공식 문서 ]
- req.app : req 객체를 통해 app 객체에 접근할 수 있음. req.app.get(’port’) 같은 식으로 사용가능
- req.body : body-parser 미들웨어가 만드는 요청의 본문을 해석한 객체
- req.cookies : cookie-parser 미들웨어가 만드는 요청의 쿠키를 해석한 객체
- req.ip : 요청의 ip 주소가 담겨 있음
- req.params : 라우트 매개변수에 대한 정보(path variable)
- req.query : 쿼리스트링에 대한 정보
- req.signedCookies : 서명된 쿠키들은 req.cookies 대신 여기에 있음
- req.get(헤더 이름) : 헤더의 값을 가져오고 싶을 때 사용하는 메서드
에러 처리 미들웨어
app.use( (req, res, next) => { const error = new Error(`${req.mehotd} ${req.url} 라우터가 없습니다.`); error.status = 404; next(error); }); app.use(
Typescript로 Express 실행하기
- node.js에 기반한 웹 애플리케이션 개발할 때, 파일에 변경사항이 발생하면 저절로 애플리케이션이 재실행되도록 도와주는 패키지임.
npm install nodemon nodemon --exec ts-node <.ts file path> npm install -D @types/node nodemon ts-node cross-env tsconfig-paths