1. 라우터 분리란?
- 기능, 도메인(업무 영역), 리소스 기준 등으로 라우트를 분리해 놓는 방식이다.
- 예: user 관련 엔드포인트는 routes/user.js, posts 관련 엔드포인트는 routes/post.js 등에 배치.
- 장점
- 코드 구조가 깔끔해진다.
- 여러 파일로 나누어 작성하므로 팀 협업 시 충돌을 줄일 수 있다.
- 유지보수가 쉬워진다. (수정, 추가가 용이)
2. 라우터 분리 예시
📁 my-project
┣ 📁 routes
┃ ┣ 📜 user.js
┃ ┗ 📜 index.js
┣ 📜 app.js
┗ ...
위와 같은 구조로 app.js에서 user와 index 파일로 분리 후 라우터를 분리해보자.
const express = require('express');
const router = express.Router();
//Get / 라우터
router.get('/', (req, res) => {
res.send('Hello, Express');
});
module.exports = router;
index.js 파일 내부에 위와 같이 작성하였다.
여기서 핵심은 express.Router()와 이렇게 받아온 router 객체를 다시 module.exports 로 넘겨준 것이다.
const express = require('express');
const router = express.Router();
//Get / 라우터
router.get('/', (req, res) => {
res.send('Hello, User');
});
module.exports = router;
마찬가지로 user.js 파일
const express = require('express');
const morgan = require('morgan');
const cookieParser = require('cookie-parser');
const session = require('express-session');
const dotenv = require('dotenv');
const path = require('path');
dotenv.config();
const indexRouter = require('./routes/index');
const userRouter = require('./routes/user');
const app = express();
app.set('port', process.env.PORT || 3000);
app.use(morgan('dev'));
// app.use('/', express.static(path.join(__dirname, 'public')));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser(process.env.COOKIE_SECRET));
app.use(session({
resave: false,
saveUninitialized: false,
secret: process.env.COOKIE_SECRET,
cookie: {
httpOnly: true,
secure: false,
},
name: 'session-cookie',
}));
const multer = require('multer');
const fs = require('fs');
try {
fs.readdirSync('uploads');
} catch (error) {
console.error('uploads 폴더가 없어 uploads 폴더를 생성합니다.');
fs.mkdirSync('uploads');
}
const upload = multer({
storage: multer.diskStorage({
destination(req, file, done) {
done(null, 'uploads/');
},
filename(req, file, done) {
const ext = path.extname(file.originalname);
done(null, path.basename(file.originalname, ext) + Date.now() + ext);
},
}),
fileFilter: (req, file, done) => {
// 이미지 파일만 허용
if (/^image\/(jpeg|png|gif)$/.test(file.mimetype)) {
done(null, true);
} else {
done(new Error('이미지 파일만 업로드 가능합니다.'), false);
}
},
limits: { fileSize: 5 * 1024 * 1024 },
});
app.get('/upload', (req, res) => {
res.sendFile(path.join(__dirname, 'multipart.html'));
});
// app.post('/upload', upload.array('image'), (req, res) => {
// // console.log(req.file);
// console.dir(req.files);
// res.send('ok');
// });
app.post('/upload', (req, res) => {
upload.array('image')(req, res, (err) => {
if(err) {
// 에러 발생 시 -> error.html 응답
return res.sendFile(path.join(__dirname, 'public', 'error.html'));
}
if(!req.files || req.files.length == 0) {
return res.sendFile(path.join(__dirname, 'public', 'emptyFiles.html'));
}
// 성공 시
res.sendFile(path.join(__dirname, 'public', 'success.html'));
});
});
app.use('/', indexRouter);
app.use('/user', userRouter);
app.get('/', (req, res, next) => {
console.log('GET / 요청에서만 실행됩니다.');
next();
}, (req, res) => {
throw new Error('에러는 에러 처리 미들웨어로 갑니다.')
});
app.use((err, req, res, next) => {
console.error(err);
res.status(500).send(err.message);
});
app.listen(app.get('port'), () => {
console.log(app.get('port'), '번 포트에서 대기 중');
});
const indexRouter = require('./routes/index');
const userRouter = require('./routes/user');
app.use('/', indexRouter);
app.use('/user', userRouter);
지난 Node.js 기본 모듈 (CommonJS, ES모듈) 포스팅에서 알 수 있듯이 CommonJS 모듈을 통해 index.js와 user.js 를 가져온다.
그렇게 설정된 객체들은 app.use() 로 경로 설정 후, 해당 객체를 아규먼트로 구성한다.
3. 주의 사항
3.1. 각 분리된 파일의 라우터 경로를 '/'로 설정해야 한다.
//Get / 라우터
router.get('/', (req, res) => {
res.send('Hello, Express');
});
각 파일들(index.js, user.js) 에는 위와 같이 라우터가 구성되어 있는데, 실제 경로는 app.js의 use()에서 입력하므로 각 파일에서는 라우터 경로를 '/'로 설정하여야 한다.
만약 다른 경로를 입력 시 404에러가 발생한다.
3.2. 미들웨어간 순서를 조심하여야 한다.
미들웨어는 위에서 아래로 실행되며 next() 호출 시 다음 미들웨어로 넘어간다.
app.get('/', (req, res, next) => {
console.log('GET / 요청에서만 실행됩니다.');
next();
}, (req, res) => {
throw new Error('에러는 에러 처리 미들웨어로 갑니다.')
});
app.use('/', indexRouter);
app.use('/user', userRouter);
만약 위와 같이 코드가 되어있다면 우리가 실행하고자 하는 use가 아닌 app.get('/' , ~~) 가 실행된다.
app.use('/', express.static(path.join(__dirname, 'public')));
app.use('/', indexRouter);
app.use('/user', userRouter);
위와 같이 코드가 설정되있다면 static 모듈만이 실행된다.
'Node.js' 카테고리의 다른 글
데이터베이스 - MySQL 테이블 생성 (0) | 2025.01.16 |
---|---|
데이터베이스 - MySQL 설치 (0) | 2025.01.16 |
익스프레스 웹 서버 만들기 - dotenv (0) | 2025.01.15 |
익스프레스 웹 서버 만들기 - 미들웨어(multer) (0) | 2025.01.15 |
익스프레스 웹 서버 만들기 - 미들웨어 확장법 (0) | 2025.01.14 |