서버에 요청을 보낼 때는 주소를 사용하여 요청의 내용을 표현할 수 있습니다.
주소에 따라 다양한 요청을 할 수 있는데 이때 등장하는 것이 REST입니다. Node.js로 서버의 내용을 만들다 보면 Restful API들을 많이 사용하게 되는데 Restful API들을 모두 하나의 파일에 작성하면 코드의 가독성이 낮아져 점점 보기 힘들어 질 수밖에 없습니다.
그렇기 때문에 라우터 router라는 것을 이용해서 여러 파일에 알맞게 분리하여 생성을 하면 코드도 간결해지고 가독성도 좋아지게 됩니다.
라우팅이란❓
라우터는 url 또는 경로(path), HTTP 요청 메서드 즉 client의 요청을 보고 이 요청을 처리할 수 있는 곳으로 기능을 전달해주는 역할을 하며 이러한 역할을 라우팅이라고 합니다.
var express = require('express');
var app = express();
app.get('/', function(req, res) {
res.send('hello Node.js');
});
위 코드에서 app.get 같은 메서드가 바로 라우터입니다. client가 GET요청을 했고 서버는 GET 요청을 받아 "hello Node.js"로 응답을 하게 됩니다.
...
app.get('/')
app.post('/')
app.put('/')
app.delete('/')
app.get('/user')
...
그런데 앞에서 말했듯이 위처럼 라우터가 많아지게 되면 코드가 복잡해지고, 가독성을 물론 관리도 힘들어집니다.
그래서 express에서는 이러한 라우터들을 분리할 수 있는 방법을 제공합니다.
라우터 router 분리 ✅
위와 같이 먼저 routes 폴더를 만들고 그 안에 index.js와 user.js를 작성하여 만들어줍니다.
두개의 js파일은 전체적으로 똑같지만 다른 주소의 라우터 역할을 하고있습니다.
index.js에서는 get의 응답으로 "Hello Express router!"를 보내주고, user.js에서는 "Hello user"를 응답으로 보내줍니다.
그리고 app.js에 다음과 같이 코드를 작성해 줍니다.
app.js 코드 중에서 9번째 줄에서 express()를 가져오고 13, 14번째 줄에서 use()를 이용하여 미들웨어를 사용합니다.
그리고 6, 7번째 줄에서 다른 파일에 있는 라우터를 require 했습니다. 이때
indexRouter는 app.use('/')에 연결했고, userRouter는 app.use('/user')에 연결했습니다. 그러면 각 요청 get의 '/'과 get의 '/uesr '에 연결되어 있으므로, 둘이 합쳐져서 최종경로로 다음과 같이 라우터가 만들어지게 됩니다.
indexRouter ➡ GET /
userRouter ➡ GET /user
node app.js
그리고 서버를 실행하고 3000번 포트로 지정했기 때문에 localhost:3000으로 접속하게 되면 Terminal에 "3000번 포트에서 대기 중이라는" 로그가 찍히고, 다음과 같이 서버에서 지정한 응답을 받을 수 있습니다.
next('route')
앞선 [Node.js] Middleware & 익스프레스 express 프레임워크 알아보기 포스팅에서 알아보았던 next() 함수를 이용하여 다음 라우터로 넘어갈 수 있는 기능이 있습니다.
next('route')
이 기능은 라우터에 연결된 나머지 미들웨어들을 건너뛰고 싶을 때 사용합니다.
라우터는 위 코드처럼 같은 주소를 여러 개 만들 수도 있습니다. 라우터가 1개든 2개든 몇 개든 간에 next() 함수를 호출하게 된다면 무조건 다음 미들웨어로 JUMP 하여 다음 미들웨어가 실행됩니다.
5번 째줄의 첫 번째 미들웨어에서 next('route')를 호출했기 때문에 2 번째 미들웨어가 실행되지 않고 그대로 지나쳐 next() 함수를 만나서 또 3 번째 미들웨어를 그냥 넘어가 결국 2 번째, 3 번째 미들웨어는 실행되지 않게 됩니다.
첫 번째 next('route')를 호출했던 미들웨어의 주소와 일치한 15 번째 줄의 미들웨어로 JUMP 하여 실행되게 됩니다.
라우트 매개변수 패턴
const express = require('express');
const router = express.Router();
router.get('/user/:id', (req, res) => {
console.log(req.params.id);
});
라우터 주소에는 정규표현식을 비록 한 특수 패턴을 사용할 수 있습니다.
주소가 '/user/:id'로 구성되어 있습니다. 이 주소의 의미는 문자 그대로 :id를 의미하는 것이 아니라 다른 값을 넣을 수 있다는 의미입니다.
ex)
- /user/1
- /user/123
- /user/park
위처럼 /user/XX 에 해당하는 다른 값 등의 요청도 '/user/:id' 라우터가 처리하게 됩니다.
라우트 매개변수 패턴의 장점은 :id처럼 패턴에 해당하는 다른 값 등을 조회할 수 있다는 점이며, req.params 객체 안에 들어있습니다.
그리고 :id면 req.params.id로, :type이면 req.params.type으로 조회할 수 있습니다.
:id 패턴이면 req.params 객체에는 {id :park}
type 패턴이면 req.params 객체에는 {type : String}와 같이 형성됩니다.
const express = require('express');
const router = express.Router();
router.get('/user/admin', (req,res) => {
console.log('Hello, user!');
});
router.get('/admin', (req,res) => {
console.log('Hello, admin!');
});
router.get('/user/:id', (req, res) => {
console.log('route param!');
});
router.get('/user/park', (req,res) => {
console.log('Hello, park!');
});
라우트 매개변수 패턴을 사용할 때는 주의주의해야 할 점이 있습니다. ❗ 바로 일반 라우터보다 뒤에 위치해야 정상적으로 처리가 됩니다.
라우트 매개변수는 다양한 라우터를 아우르는 와일드카드역할을 하기 때문에 일반 라우터보다 뒤에 위치해야 다른 라우터를 방해하지 않기 때문입니다.
위 코드를 보면 /user/admin으로 들어가면 정상적으로 "Hello admin!"이 출력되고, /user/park으로 접속하면 "route param"이 출력되게 됩니다.
왜냐하면 일반 라우터인 '/uesr/park'이 매개변수 라우트보다 뒤에 위치하기 때문에 일반 라우터가 실행되지 않고 위에서 아래의 순서로 실행되니깐 매개변수 라우트가 실행되게 됩니다.
const express = require('express');
const router = express.Router();
router.get('/user/admin', (req,res) => {
console.log('Hello, user!');
});
router.get('/admin', (req,res) => {
console.log('Hello, admin!');
});
router.get('/user/park', (req,res) => {
console.log('Hello, park!');
});
router.get('/user/:id', (req, res) => {
console.log('route param!');
});
정상적으로 매개변수 라우트를 사용하려면 위처럼 일반 라우터가 매개변수 라우터보다 위에 위치해야 합니다.
라우터 쿼리 스트링
const express = require('express');
const router = express.Router();
router.get('/user/:id', (req, res) => {
console.log(req.params, req.query);
res.send(``);
});
app.use('/', router);
위 처럼 라우터 주소에 쿼리 스트링을 쓸 때도 있으며, 쿼리스트링의 key-value의 정보들은 req.query 객체 안에 들어있습니다.
{ id: 'park' } { limit: '5', skip: '10' }
/user/park? limit=5&skip=10의 주소로 접속하여 서버에 요청을 한다면 위와 같이 응답을 받을 수 있습니다.
라우터 그룹화
만약 주소는 같지만 메서드가 다른 코드가 있을 때 이를 하나의 덩어리로 줄일 수 있는 방법이 있습니다.
바로 router.route와 app.route입니다.
const express = require('express');
const router = express.Router();
router.get('/abc', (req, res) => {
res.send('GET /abc');
});
router.post('/abc', (req, res) => {
res.send('POST /abc');
});
router.route('/abc')
.get((req,res) => {
res.send('GET /abc');
})
.post((req, res) => {
res.send('POST /abc');
});
주소는 /abc로 같지만 HTTP 요청 메서드가 GET과 POST로 다를 때 위와 같이 router.route로 관련 있는 코드끼리 묶을 수 있어 가독성이 좋아지게 됩니다.
'Framework > Node.js' 카테고리의 다른 글
[Node.js] Middleware & 익스프레스 express 프레임워크 알아보기 (0) | 2024.04.17 |
---|---|
[Node.js] dotenv 알아보기 (0) | 2024.04.07 |
[Node.js] process.env 알아보기 (0) | 2024.04.07 |
[Node.js] 동기 & 비동기 / Non-blocking & blocking (0) | 2024.03.30 |