네트워크 측면에서 이해해봅시다.
우리가 컴퓨터를 통해 다른 컴퓨터와 통신할 때, 여러 네트워크 경로를 지나게 됩니다. 이렇게 통신을 위해 지나가는 데이터 송수신 경로를 라우트
라고 합니다.
라우트는 라우터
라고 하는 특수 컴퓨터 장치에 의해 연결되는데,
라우터는 최적의 경로(라우트)를 찾아주는 기능을 합니다.
라우터는 최적의 경로를 찾아주기 위해 라우팅
이라는 프로토콜을 사용합니다. 라우팅에는 일정한 기준이 있어, 꼭 최단 거리라고 해서 최적 경로는 아닙니다.
이것이 네트워크 통신 입장에서 설명하는 개념입니다.
이는 웹 서버 구현 측면에서는 다른 의미로 설명되는데, 이에 대해 알아봅시다.
웹 서버를 구현할 때, 우리는 각 웹 페이지를 URL (웹 페이지 주소)
로 구분합니다.
사용자는 URL 을 입력하여 접속하고, 서버는 해당 URL 에 대한 요청에 응답합니다.
이렇게 서버에서 제공하는 URL 의 주소, 즉 접속가능한 경로를 라우트
라고 합니다.
라우트는 다음과 같이 표현됩니다.
/users
사용자가 주소를 입력해 접속하므로, 각 페이지에 대한 라우트를 여러개 만들어야겠죠?
회원 가입, 회원 탈퇴, 회원 정보 편집, 로그아웃 등의 라우트를 만든다고 합시다.
/join
/user-logout
/profile-edit
/logout
라우트는 만들었지만... 이런식이라면 정리도 안되고 불편합니다.
그래서 기능에 따라 분류하여 라우트를 생성한다고 합시다.
/join
/users/delete
/users/edit
/users/logout
회원 탈퇴, 회원 정보 편집, 로그아웃 등은 "회원" 이라는 상황 안에서 수행되는 기능이므로, users
를 기준으로 라우트를 분류합니다.
이렇게, 최종적으로 라우트를 분류하는 기준이 되는 것을 라우터
라고 합니다.
위 상황에서는 user 라우터에 의해 분류된다고 할 수 있습니다.
라우터로 각 라우트를 분류했다면, 유저가 경로에 접속했을 때 서버가 이에 응답해야겠죠?
클라이언트의 라우트 요청에 대해 서버가 응답하는 방식을 결정하는 것을 라우팅
이라고 합니다.
app.get("/users", handleUser);
// 라우팅 처리
/users
라는 라우트에 대한 GET 요청에, handleUser 라는 컨트롤러 를 사용하여 응답하도록 하고있습니다.
이렇게, 라우트 요청에 서버가 응답하는 방식(handleUser) 을 결정하는 것이 라우팅
입니다.
Express 에서 라우터를 사용하여 요청을 처리하는 방식을 알아보겠습니다.
Express 공식 문서에서는 라우터를 다음과 같이 설명하고 있습니다.
- 라우터는 요청을 처리하는 미니 어플리케이션(app)
- app 의 메소드를 사용할 수 있음
- app 은 라우터를 미들웨어처럼 사용
즉, 라우터는 라우트 요청을 처리할 때 app 이 혼자 모든 요청에 대해 처리하는 것을 방지하기 위한 미니 어플리케이션
으로, app
과 비슷한 방식으로 사용할 수 있다는 것입니다.
다음과 같은 라우트가 존재한다고 합시다.
/users/:id -> See User
/users/logout -> Log Out
/users/edit -> Edit My Profile
/users/delete -> Delete My Profile
/videos/:id -> Watch Video
/videos/:id/edit -> Edit Video
/videos/:id/delete -> Delete Video
/videos/upload -> Upload Video
이를 라우터 없이 처리하려면...
app.get("/users/:id", handleUser); -> See User
app.get("/users/logout", handleUserLogout); -> Log Out
.
.
.
이렇게 하나하나 써야겠죠?
생각만 해도 가독성 떨어지고 불편합니다...
반면, 라우터를 사용하여 라우터에서 요청을 처리하도록 한다면 어떻게 될까요?
app.use("/videos", videoRouter);
app.use("/users", userRouter);
먼저, 각 경로를 /videos
에서 이어지는 것과 /users
에서 이어지는 것으로 분류했습니다.
/videos
경로는 videoRouter
가, /users
경로는 userRouter
가 처리하도록 하고있습니다.
app 은 라우터를 미들웨어처럼 사용할 수 있으니, use() 를 통해 라우터를 이용합니다.
그렇다면, 우리가 /users 로 이어지는 경로에 접속했을 때, userRouter 에 들어가겠죠?
const userRouter = express.Router();
// 라우터 생성
userRouter.get("/logout", logout);
// "/users/logout" 경로에 대한 GET 요청 처리
userRouter.get("/edit", edit);
userRouter.get("/remove", remove);
라우터는 요청을 처리하는 미니 어플리케이션과 동일하게 취급할 수 있으므로, 생성된 라우터는 app 과 동일한 방식으로 GET 요청을 처리 가능합니다.
동작 순서는 다음과 같습니다.
/users/logout 라우트 요청
app
: /users 로 시작하니까, userRouter 에 처리를 맡기자!
userRouter
: /logout 으로 이어지니까, logout 컨트롤러가 처리하게 하자!
logout 컨트롤러
: 요청에 대해 응답합니다~
이렇게 요청에 대한 응답이 처리됩니다.
라우터를 사용하여 분류하면, 가독성 있고 편하게 라우팅 처리가 가능합니다.