6 minute read

라우트 개요

보통, Node.js(Express)는 Application 파일이 app.js 혹은 index.js 파일 하나밖에 존재하지 않는다. 즉, 수십개 이상의 URL을 모두 하나의 파일에 작성해야 한다. 어플리케이션 파일이 길어지는 것을 방지하기 위해 Route를 모듈화 시켜 분리시키는 것을 권장한다.

사용법

// 1. 라우터 객체 참조
const router = express.Router();

// 2. 라우팅 함수 등록
router.route('/member/select').get(...);
router.route('/member/insert').post(...);
...

// 3. 라우터 객체 미들웨어 등록
app.use('/', router);

router 객체의 route() 메소드를 통해 요청 경로를 지정할 수 있으며, get()이나 post() 등의 메소드를 호출하면 실행될 함수를 등록할 수 있다.

기본

const express = require('express');
const app = express();

// 1. 라우터 객체 참조
var router = express.Router();

// 2. 라우팅 함수 등록
router.route('/select').get(function(req, res) {
  console.log('start >> GET /member/select');
});

// 3. 라우터 객체 미들웨어 등록
app.use('/member', router);

/*  기본 라우트 핸들러  ==> 없어도 된다. 위에 라우터 객체로만 구현해도 된다.
app.get('/', (req, res) => {
  res.send('Hello, World!');
});
*/

http://호스트주소:포트/member/select 요청시 정상 작동한다.

app.use([기준URL], [라우터객체])
마치 톰캣의 <Context DocBase=''> 설정과 비슷하다.
router.route([URL])
톰캣의 DocBase 기준으로 스프링의 컨트롤러 URL 매핑과 비슷하다.

궁금한점이 생겼다. 만약 순서를 바꾸면 어떻게 될까?

// 1. 라우터 객체 참조
var router = express.Router();

// 3. 라우터 객체 미들웨어 등록
app.use('/member', router);

// 2. 라우팅 함수 등록
router.route('/select').get(function(req, res) {
  console.log('start >> GET /member/select');
  res.send('{success: true}');
	
});

/*  기본 라우트 핸들러  ==> 없어도 된다. 위에 라우터 객체로만 구현해도 된다.
app.get('/', (req, res) => {
  res.send('Hello, World!');
});
*/

결과는 정상 작동한다.
즉, 객체를 미들웨어로 먼저 등록하고 함수 내용을 작성해도 무방하다.

라우터 체이닝

// 2. 라우팅 함수 등록
router.route('/select')
  .get(function(req, res) {
    console.log('start >> GET /member/select');
  })
  .post(function(req, res) {
    console.log('start >> POST /member/select');
  })
  .put(function(req, res) {
    console.log('start >> PUT /member/select');
  });
  

메소드 체이닝으로 나열했다. 간단하므로 설명은 생략한다.

라우트 모듈화

routes 관리 디렉토리 생성

mkdir /routes

/routes/member.js

const express = require('express');

// 1. 라우터 객체 참조
const router = express.Router();

// 2. 라우팅 함수 등록 (라우트함수를 정의하고)
router.get('/select', (req, res) => {
    console.log('start >> GET /member/select');
    res.send("고객정보조회");
})
.post('/insert', (req, res) => {
    console.log('start >> POST /member/insert');
    res.send("신규고객추가");
})
.put('/update', (req, res) => {
    console.log('start >> PUT /member/update');
    res.send("고객정보수정");
})
.delete('/delete', (req, res) => {
    console.log('start >> delete /member/delete');
    res.send("기존고객삭제");
});

//3. 모듈 익스포트 (하나의 파일로 모듈화 하여 내보낸다)
module.exports = router;  

/app.js

const express = require('express');
const app = express();

// 작성한 모듈 참조
var router = require('./routes/member.js');

// 4. 라우터 객체 미들웨어 등록
app.use('/member', router);

/*  기본 라우트 핸들러  ==> 없어도 된다. 위에 라우터 객체로만 구현해도 된다.
app.get('/', (req, res) => {
  res.send('Hello, World!');
});
*/

메인 어플레케이션이 매우 간소화 되었다. 길이가 길 수록 더욱 코드는 간결해지겠다.

라우터 NEXT 기능(1)

/routes/index.js

const express = require('express');

// 1. 라우터 객체 참조
const router = express.Router();

// 2. 라우팅 함수 등록
// 다수의 핸들러 함수를 지정해주려면 함수의 로직 끝에 꼭 'next()'를 붙여주도록 하자.
router.get('/', (req, res, next) => {
    console.log('step1 선행 프로세스 진행중...');  // 실행O
    next();
}, (req, res, next) => {
    console.log('step2 선행 프로세스 진행중...');  // 실행O
    next();
}, (req, res, next) => {
    console.log('step3 선행 프로세스 진행중...');  // 실행O
    next();
});

router.all('/',(req,res)=>{
    res.send("{message:welcome}");  // 실행O
})

//3. 모듈 익스포트 (하나의 파일로 모듈화 하여 내보낸다)
module.exports = router;

위 예시는 미들웨어를 활용해서 무언가 처리하고 싶을때 쓸 수있을듯 하다.

라우터 NEXT 기능(2)

/routes/index.js

const express = require('express');

// 1. 라우터 객체 참조
const router = express.Router();

// 2. 라우팅 함수 등록
// 다수의 핸들러 함수를 지정해주려면 함수의 로직 끝에 꼭 'next()'를 붙여주도록 하자.
router.get('/', (req, res, next) => {
    console.log('step1 선행 프로세스 진행중...');  // 실행O
    next('route');  // 미들웨어를 모두 건너띄고 즉시 URL 매핑 수행함.
}, (req, res, next) => {
    console.log('step2 선행 프로세스 진행중...');  // 실행X
    next(); 
}, (req, res, next) => {
    console.log('step3 선행 프로세스 진행중...');  // 실행X
    next(); 
});

router.all('/',(req,res)=>{
    res.send("{message:welcome}");  // 실행O
})

//3. 모듈 익스포트 (하나의 파일로 모듈화 하여 내보낸다)
module.exports = router;

첫 번째 라우터의 첫 번째 미들웨어에서 next('router')를 호출하자 두 번째, 세 번째 미들웨어는 실행되지 않는다. 대신 주소와 일치하는 다음 라우터로 넘어간다. 위 예시는 미들웨어 처리 도중에 건너띄어야 하는 상황이면 활용 가능할듯..

라우터 컨트롤러 구조잡기

참고한 블로그) https://firework-ham.tistory.com/59

AS-IS 구조는 다음과 같다.

/app.js

const express = require('express');
const app = express();

// 작성한 모듈참조
var idxRouter = require('./routes/index.js');
var memRouter = require('./routes/member.js');

// 라우터 객체 미들웨어 등록
app.use('/', idxRouter);
app.use('/member', memRouter);

AS-IS 구조 특징

  1. AS-IS 구조는 router 파일이 생성될때마다 app.js에 url과 파일을 등록해주어야 한다.
  2. url관리와 서비스 로직을 하나의 router 파일에서 해야 하기에 가독성이 떨어진다.

    [url관리를 따로 관리하는 파일]과 [서비스 로직이 있는 파일]로 분리하여 가독성과 코드 관리가 좋은 방식으로 변경이 필요하다.

step1. url 관리하는 router 파일 생성

: 아래 step1 작업을 해주면 라우터 전용 인터페이스가 생긴다.

/routes/index.js (인터페이스 역할)

const express = require('express');
const router = express.Router();

const main = require('./main.js');
const umemberser = require('./member.js')

router.use('/', main);
router.use('/user', member);

module.exports = router;

/routes/main.js (모듈)

const express = require('express');
const router = express.Router();

router.get('/',(req,res)=>{
    res.send("{message:welcome}");
})

module.exports = router;

/routes/member.js (모듈)

const express = require('express');
const router = express.Router();

router.get('/select', (req, res) => {
    console.log('start >> GET /member/select');
    res.send("고객정보조회");
})
.post('/insert', (req, res) => {
    console.log('start >> POST /member/insert');
    res.send("신규고객추가");
})
.put('/update', (req, res) => {
    console.log('start >> PUT /member/update');
    res.send("고객정보수정");
})
.delete('/delete', (req, res) => {
    console.log('start >> delete /member/delete');
    res.send("기존고객삭제");
});

module.exports = router;  

/app.js (메인에서 인터페이스 호출)

// 이전 코드
// var idxRouter = require('./routes/index.js');
// var memRouter = require('./routes/member.js');
//
// app.use('/', idxRouter);
// app.use('/member', memRouter);

// 변경코드
const routes = require('./routes');

app.use(routes);

메인 코드가 매우 간략해졌다..

이렇게 변경하면 url 변경 또는 router 파일 변경시 app.js를 수정하지 않고 인터페이스 역할의 '/router/index.js' 를 수정하면 url 및 api 관리가 가능해진다. 정말 간단하게 변경했지만 관리하는 관점에서는 대폭 개선된다. 정상적으로 api가 호출되는지 한번 확인한다.

step2. url 관리와 서비스 코드 분리

인터페이스 역할의 /index.js 안에 사용중인 모듈이 모두 같은 디렉토리안에 있있었다. 각각의 모듈들에게 디렉토리를 만들어주고 이동시킨다.

mkdir /routes/main
mkdir /routes/member

mv /routes/main.js /routes/main
mv /routes/member.js /routes/member

이제 본격적으로 이 모듈을 서비스로 만들기위한 작업을 수행한다.

/routes/main/index.js (모듈)
아까 main.js 파일이 index.js 파일명으로 바뀌었다고 생각하면 된다.
const express = require('express');
const router = express.Router();
const controller = require('./main.controller');  // (변경분)추가

// ASIS
/*
router.get('/',(req,res)=>{
    res.send("{message:welcome}");
})
*/

// TO-BE
router.get('/', controller.main);  // (변경분)컨트롤러 내용 호출

module.exports = router;

/routes/member/index.js (모듈)
아까 member.js 파일이 index.js 파일명으로 바뀌었다고 생각하면 된다.
const express = require('express');
const router = express.Router();
const controller = require('./member.controller');  // (변경분)추가

// ASIS
/*
router.get('/select', (req, res) => {
    console.log('start >> GET /member/select');
    res.send("고객정보조회");
})
.post('/insert', (req, res) => {
    console.log('start >> POST /member/insert');
    res.send("신규고객추가");
})
.put('/update', (req, res) => {
    console.log('start >> PUT /member/update');
    res.send("고객정보수정");
})
.delete('/delete', (req, res) => {
    console.log('start >> delete /member/delete');
    res.send("기존고객삭제");
});
*/

// TO-BE
// 2. 라우팅 함수 등록 TO-BE
router.get('/select', controller.getMember);    // (변경분)컨트롤러 내용 호출
router.get('/insert', controller.insertMember); // (변경분)컨트롤러 내용 호출
router.get('/update', controller.updateMember); // (변경분)컨트롤러 내용 호출 
router.get('/delete', controller.deleteMember); // (변경분)컨트롤러 내용 호출

module.exports = router;  

모듈 내용에서 변경분을 보면 [모듈명.controller] 으로 다른 모듈을 임포트하고있다. 해당 컨트롤러들을 만들어 준다.

touch routes/main/main.controller.js
touch routes/member/member.controller.js

routes/main/main.controller.js (컨트롤러 역할)

exports.main = (req, res, next) => {
    console.log('main.controller.js >> main()');
    //res.render('index', { title: 'Express' });
}

routes/member/member.controller.js (컨트롤러 역할)

exports.getMember = (req, res, next) => {
    console.log('member.controller.js getMember()');
}
exports.insertMember = (req, res, next) => {
    console.log('member.controller.js insertMember() >> ');
}
exports.updateMember = (req, res, next) => {
    console.log('member.controller.js updateMember() >> ');
}
exports.deleteMember = (req, res, next) => {
    console.log('member.controller.js deleteMember() >> ');
}


모듈별로 생성해주었으니 이제 메인에서 참조 경로를 수정해준다.

/routes/index.js (인터페이스 역할)

const express = require('express');
const router = express.Router();

// AS-IS
// const main = require('./main.js');
// const user = require('./member.js')

// TO-BE
const main = require('./main/index.js');
const member = require('./member/index.js')

router.use('/', main);
router.use('/member', member);

module.exports = router;

정상 작동 확인

구현완료

Leave a comment