라우팅 (Routing) 정의하기 🚦
Express.js의 가장 핵심적인 기능 중 하나는 라우팅(Routing) 입니다. 라우팅은 클라이언트의 특정 요청, 즉 HTTP 메소드(GET, POST 등)와 URL 경로(Path)의 조합에 대해 애플리케이션이 어떻게 응답할지를 결정하는 메커니즘을 말합니다.
예를 들어, 사용자가 브라우저에서 https://my-site.com/users 주소로 접속(GET 요청)했을 때 사용자 목록을 보여주고, https://my-site.com/users 주소로 어떤 데이터를 전송(POST 요청)했을 때는 새로운 사용자를 생성하도록 만드는 것이 바로 라우팅의 역할입니다.
1. 기본 라우팅 구조
Express에서의 라우팅 정의는 매우 직관적이고 간결합니다. 기본 구조는 다음과 같습니다.
app.METHOD(PATH, HANDLER)
- app: express()를 통해 생성된 Express 애플리케이션 인스턴스입니다.
- METHOD: 소문자로 된 HTTP 요청 메소드입니다. (예: app.get, app.post, app.put, app.delete)
- PATH: 서버의 경로(URI)입니다. 문자열로 정의합니다.
- HANDLER: 라우트가 일치했을 때 실행될 함수입니다. 이 함수는 항상 요청(request) 객체와 응답(response) 객체를 인자로 받습니다. ((req, res) => { ... })
예시:
const express = require('express');
const app = express();
const port = 3000;
// 사용자가 루트 경로('/')로 GET 요청을 보냈을 때의 처리
app.get('/', (req, res) => {
res.send('Welcome to the home page!');
});
// 사용자가 '/about' 경로로 GET 요청을 보냈을 때의 처리
app.get('/about', (req, res) => {
res.send('This is the about page.');
});
// 사용자가 '/login' 경로로 POST 요청을 보냈을 때의 처리
app.post('/login', (req, res) => {
// 실제로는 여기서 사용자 인증 로직이 수행됩니다.
res.send('Login attempt successful!');
});
app.listen(port, () => {
console.log(`Server is running on port ${port}`);
});
2. 라우트 파라미터 (Route Parameters)
URL 경로의 일부를 변수처럼 사용하여 동적인 값을 받아올 수 있습니다. 예를 들어, 특정 ID를 가진 사용자의 정보를 조회하는 /users/123과 같은 URL을 처리할 때 유용합니다.
경로 문자열에 콜론(:)을 사용하여 파라미터를 정의하고, 핸들러 함수 내에서 req.params 객체를 통해 해당 값에 접근할 수 있습니다.
예시:
// :userId 부분에 어떤 값이든 올 수 있습니다.
app.get('/users/:userId', (req, res) => {
// req.params는 { userId: '입력된값' } 형태의 객체가 됩니다.
const userId = req.params.userId;
res.send(`Fetching profile for user with ID: ${userId}`);
});
// 여러 개의 파라미터 사용
app.get('/users/:userId/posts/:postId', (req, res) => {
const { userId, postId } = req.params;
res.send(`User ${userId} requested post ${postId}`);
});
3. 쿼리 스트링 (Query Strings)
URL 경로 뒤에 ?로 시작하여 key=value 형태로 전달되는 데이터는 req.query 객체를 통해 접근할 수 있습니다. 주로 검색이나 필터링, 페이징 기능에 사용됩니다.
예시:
// /search?category=books&term=node.js 요청에 대한 처리
app.get('/search', (req, res) => {
// req.query는 { category: 'books', term: 'node.js' } 형태의 객체가 됩니다.
const { category, term } = req.query;
res.send(`Searching in category '${category}' for term '${term}'`);
});
4. 라우터 모듈화 (express.Router)
애플리케이션의 규모가 커지면 app.js 파일 하나에 모든 라우팅 코드를 작성하는 것은 유지보수를 매우 어렵게 만듭니다. 기능별로 라우팅 코드를 별도의 파일로 분리하여 관리하는 것이 좋은데, 이때 express.Router를 사용합니다.
express.Router는 미니 Express 애플리케이션처럼 동작하는, 라우팅 및 미들웨어 기능을 가진 독립적인 객체입니다.
Java 개발자를 위한 비유: express.Router를 사용하는 것은 Spring Boot에서 @RestController와 @RequestMapping("/api/users") 어노테이션을 사용하여 User 관련 API를 UserController.java 파일에 따로 분리하여 관리하는 것과 완벽하게 동일한 개념입니다.
라우터 분리 예시:
1) 라우터 파일 생성 (routes/userRouter.js)
const express = require('express');
const router = express.Router(); // Router 인스턴스 생성
// 이 파일 내에서의 '/'는 '/users'를 기준으로 한 상대 경로가 됩니다.
// GET /users/
router.get('/', (req, res) => {
res.send('List of all users');
});
// GET /users/search
router.get('/search', (req, res) => {
res.send('Search for a user');
});
// GET /users/:id
router.get('/:id', (req, res) => {
res.send(`Profile for user with ID: ${req.params.id}`);
});
module.exports = router; // 생성한 라우터 객체를 모듈로 내보냅니다.
2) 메인 파일에서 라우터 사용 (app.js)
const express = require('express');
const app = express();
const port = 3000;
// 우리가 만든 userRouter 모듈을 가져옵니다.
const userRouter = require('./routes/userRouter');
// '/users'라는 경로로 시작하는 모든 요청은 userRouter에게 처리를 위임합니다.
app.use('/users', userRouter);
// 다른 라우터도 추가할 수 있습니다.
// const postRouter = require('./routes/postRouter');
// app.use('/posts', postRouter);
app.get('/', (req, res) => {
res.send('Welcome to the Main App!');
});
app.listen(port, () => {
console.log(`Server is running on port ${port}`);
});
이제 app.js 파일은 어떤 경로 그룹을 어떤 라우터가 담당하는지에 대한 "교통정리" 역할만 하고, 실제 세부적인 라우팅 로직은 각 라우터 파일이 책임지게 됩니다. 이를 통해 코드의 구조가 훨씬 깔끔해지고 기능별로 관리하기 용이해집니다.
Express의 핵심 기능인 라우팅에 대해 알아보았습니다. URL 경로와 파라미터, 쿼리를 기반으로 요청을 처리하고, express.Router를 통해 코드를 체계적으로 구성하는 방법을 익혔습니다.
'프로그래밍 > NODEJS 강좌 BY GEMINI' 카테고리의 다른 글
| 템플릿 엔진 사용하기 (선택 사항) 🎨 (1) | 2025.06.18 |
|---|---|
| 미들웨어 (Middleware) 활용하기 🔗 (1) | 2025.06.16 |
| 5️⃣ Express.js로 강력한 웹 애플리케이션 구축하기 🌐 (1) | 2025.06.10 |
| Async/Await: 동기 코드처럼 비동기 코드 작성하기 MAGIC ✨ (1) | 2025.06.10 |
| 프로미스(Promises)로 우아하게 비동기 처리하기 ✨ (2) | 2025.06.09 |