라우팅
express에서 라우팅이라는 개념은 클라이언트로부터 요청받은 URL과 뷰를 매칭시키는 것이라고 할 수 있습니다.
우리가 웹 브라우저에 google.com 이라고 입력하면 해당 구글 웹서버가 응답하여 매칭되는 화면을 띄우는 것이라고 할 수 있죠.
아래 예시를 보면 , 같은 도메인 주소(www.naver.com) 에서 path에 따라 다른 페이지를 보여주는 역할을 라우터가 해주는 것입니다. 여기서 path는 webtoon과 blog 이네요.
https://www.naver.com/webtoon
https://www.naver.com/blog
//예시를 들고자 편하게 적은 것이며 실제와 다릅니다.
웹을 제작할 때 초기에 해당 코드를 많이 볼 수 있습니다. 페이지가 있어야 그 페이지를 구성하고 꾸미겠죠?
app.get('/', (req, res) => {
res.send('Read me!')
});
이처럼 어떤 path로 들어왔을 때 어떻게 응답할 건지 지정해주는 것이 routing이다.
만약 root path로 들어왔을 때는 "Read me!"를 띄우고 'hi' path로 들어왔을 때는 "Hi. This is "hi" path using express router"를 화면에 띄워본다면?
const express = require('express')
const app = express()
const port = 3000
app.get('/hi', (req, res) => {
res.send('Hi. This is "hi" path using express router')
})
app.get('/', (req, res) => {
res.send('Read me!')
})
app.listen(port, () => {
console.log(`listening at http://localhost:${port}`)
})
만약 지정해논 path 외로 들어간다면?
https://localhost:3000/text 로 들어갔을 때 Cannot GET /text 라고 뜹니다. 여기서 GET 은 뭘까요? http 메서드 입니다.
해당 경로의 resource(자원)에 대해 어떤 요청을 하는 지에 대한 표현을 http 메서드 라고 합니다.
여기선 GET이 쓰였는데, 이외에도 HEAD, POST, PUT, DELETE, CONNECT 등등이 있습니다.
위의 경우에는, GET으로 'hi' path가 요청 됐을 때, 해당 문구를 화면에 응답하는 것이죠.
페이지 간 이동
'/' 페이지에서 '/hi' 페이지로 이동하려면?
<a> 태그만 사용하면 쉽게 할 수 있습니다. 옵션 href에 이동할 '/hi'를 넣어주면 되죠.
app.get('/', (req, res) => {
res.send('Hello World! <a href="/hi">Move to "Hi" Page!</a>')
})
라우터 객체
만약 페이지가 점점 더 많아지면 복잡해지겠죠? 그것을 간단히 하기 위해서는 라우터 객체를 이용할 수 있습니다.
라우터 객체를 이용하게 되면 비슷한 기능들끼리 모듈로 묶어볼 수 있다고 하네요!
<index.js 파일>
const express = require('express')
const app = express()
const port = 3000
app.get('/goods/list', (req, res) => {
res.send('상품 목록 페이지')
})
app.get('/goods/detail', (req, res) => {
res.send('상품 상세 페이지')
})
app.get('/user/login', (req, res) => {
res.send('로그인 페이지')
})
app.get('/user/register', (req, res) => {
res.send('회원가입 페이지')
})
app.listen(port, () => {
console.log(`listening at http://localhost:${port}`)
})
위와 같은 페이지 4개가 있다고 해봅시다. 4개만 했는데도 코드가 길어졌네요. 이것을 라우터 객체를 이용해보면
우선 디렉토리를 하나 생성해봅시다. 'routes' 디렉토리 안에 'goods.js' 파일을 생성해보죠.
goods.js 안에 할 일은
1. router 객체 생성
2. /goods 경로에 해당하는 하위 경로 요청에 대한 라우팅을 해줍니다.
<goods.js 파일>
const express = require('express');
const router = express.Router(); // 라우터 객체 생성
router.get('/list', function(req, res, next) {
res.send('Router 상품 목록 페이지')
next()
});
router.get('/detail', function(req, res, next) {
res.send('Router 상품 상세 페이지')
next()
});
// 연속으로 등록된 callback 메소드의 순서를 제어하기위해 다음 미들웨어를 호출하고 싶다면 next('route')를 실행시키면 된다
//지금은 next()이므로 그냥 동작한다.
module.exports = router; //외부에서 쓸 수 있도록 함
이렇게 되면, /goods 경로로 들어온 요청을 라우터 객체가 받아서 하위 경로로 연결해주는 역할을 하는것이죠.
약간 달라진 점이 몇 군데 보이죠?
index.js에서는 const app = express(); 를 한 후에, app.get() 을 해줬다면
router 파일에서는 router 객체를 이용하게 됩니다. const router = express.Router(); 를 한 후에, router.get()을 해줍니다!
이제 index.js 파일을 수정해줘야죠.
// 생략
// 추가
const goodsRouter = require('./routes/goods'); //goods.js에 있는 라우터 연결
app.use('/goods', goodsRouter) //'/goods'로 요청이 들어오면 goodsRouter를 실행시킨다.
//아래 코드는 주석처리!
// app.get('/goods/list', (req, res) => {
// res.send('상품 목록 페이지')
// })
// app.get('/goods/detail', (req, res) => {
// res.send('상품 상세 페이지')
// })
app.get('/user/login', (req, res) => {
res.send('로그인 페이지')
})
app.get('/user/register', (req, res) => {
res.send('회원가입 페이지')
})
app.listen(port, () => {
console.log(`listening at http://localhost:${port}`)
})
router를 사용하게 되면, 페이지 안에서 또 관련된 기능들끼리 구성하게 할 수 있기 때문에 express에서는 router를 하나의 미니앱이라고 부르기도 한다네요ㅎㅎ 귀엽군요
/goods 처럼 /user 도 똑같이 해봅시다.
1. routes 디렉토리 아래에 'user.js' 파일 생성
2. 'user.js' 파일에서 라우터 객체 생성 후 get 요청. (module.export를 해줘야 index.js와 연결됩니다!)
3. 'index.js' 파일에서 라우터 파일을 요쳥하여 라우터 객체 실행
이렇게 라우터 객체를 이용하고나면 index.js 파일이 훨씬 간결해집니다.
<index.js 코드>
const express = require('express')
const app = express()
const port = 3000
const goodsRouter = require('./routes/goods'); //goods.js에 있는 라우터 연결
app.use('/goods', goodsRouter) //'/goods'로 요청이 들어오면 goodsRouter에게 보내게 된다.
const userRouter = require('./routes/user'); //user.js에 있는 라우터 연결
app.use('/user', userRouter) //'/user'로 요청이 들어오면 userRouter에게 보내게 된다.
app.listen(port, () => {
console.log(`listening at http://localhost:${port}`)
})
라우터를 배웠고, 다음 글에서 미들웨어에 대해 배울 것인데요! 그전에
미들웨어가 동작하는 레벨을 먼저 다뤄보면 좋을 것 같습니다.
미들웨어 동작레벨은
애플리케이션 레벨과 라우터 레벨이 있습니다.
단계는 애플리케이션 레벨 -> 라우터 레벨 순으로 동작합니다.
쉽게 애플리케이션 분기와 라우터 분기로 나눈 것이라고만 봐도 무방한데요
이렇게 나눔으로써 더 세세하게 요청 URL을 분리해서 제어가 가능합니다.
애플리케이션 레벨
const goodsRouter = require('./routes/goods'); //goods.js에 있는 라우터 연결
const userRouter = require('./routes/user'); //user.js에 있는 라우터 연결
const app = express()
app.use('/user', userRouter) //'/user'로 요청이 들어오면 userRouter에게 보내게 된다.
app.use('/goods', goodsRouter) //'/goods'로 요청이 들어오면 goodsRouter에게 보내게 된다.
index.js 의 코드가 애플리케이션 단계입니다.
app.use() 를 이용해서 '/goods'와 '/users'로 URL을 분리하여 처리하도록 하는 것입니다.
또 callback 인자에 (app.use('/goods',goodsRouter) express.Router() 오브젝트를 생성해서 넣음으로써 라우터 단계에서 URL 제어도 가능하도록 등록한 것이죠.
동작 레벨 (라우터 레벨)
위의 goods.js와 같은 코드가 라우터 단계의 미들웨어입니다.
'/goods'를 통해 들어온 요청은 해당 코드에서 '/list'와 '/detail'로 나뉩니다.
공부하면서 정리한 내용이라 잘못된 내용이 있을 수 있습니다.
따뜻한 피드백은 환영입니다♥
'언어 > node.js' 카테고리의 다른 글
Node.js를 이용한 크롤링 (2) | 2021.10.12 |
---|---|
html의 유용한 기능 (0) | 2021.08.31 |
[npm] 필요한 모듈 한번에 설치하기 (0) | 2021.07.28 |
[개념] 비동기 처리를 위한 문법 (ES6) (0) | 2021.07.20 |
[개념] JS와 ES6 문법 (0) | 2021.07.20 |