포스트

라우팅과 라우터

라우팅과 라우터

[Archive] 이 글은 2021년에 다른 플랫폼에서 작성한 글을 이전하며 재구성한 것입니다.
내용 중 일부는 현재 기준과 맞지 않을 수 있습니다.

라우터와 라우팅

라우터(router)는 말 그대로 라우팅(routing)을 수행하는 역할을 한다.

일반적으로 라우팅은 ‘어떤 네트워크 안에서 통신 데이터를 보낼 경로를 선택하는 과정’으로 정의할 수 있다.
중요한 부분은 ‘경로를 선택하는 과정’이다.

이 글에서는 라우팅을 네트워크나 특정 프레임워크의 기능이 아니라, 프로그래밍에서의 분기와 매핑 문제로 바라본다.

라우팅이란 무엇인가

프로그래밍에서 선택은 무언가를 임의로 고르는 행위가 아니다.
상태(state) 가 주어지고, 그 상태에 따라 정해진 처리가 수행된다.

라우팅의 본질은 상태와 처리 로직을 연결하는 방식에 있다.


조건문으로 보는 라우팅

가장 익숙한 라우팅 방식은 조건문이다.

1
2
3
4
5
6
7
8
9
10
11
switch (action) {
  case "print":
    print();
    break;
  case "run":
    run();
    break;
  case "stop":
    stop();
    break;
}

이 방식은 직관적이고 이해하기 쉽다.
하지만 조건이 늘어날수록 다음과 같은 문제가 생긴다.

  • 분기 수 증가에 따른 가독성 저하
  • 새로운 조건 추가 시 코드 수정 범위 증가
  • 분기 로직과 실행 로직이 강하게 결합됨

조건문 자체는 사라질 수 없지만, 조건문에 모든 책임을 지우는 구조는 빠르게 복잡해진다.


조건문에서 매핑으로

조건 분기를 코드가 아닌 데이터 구조로 옮기면 조금 다른 모습으로 바뀐다.

1
2
3
4
5
6
7
8
const actions = {
  print: () => {},
  run: () => {},
  stop: () => {},
};

const runner = actions[action];
runner && runner();

중요한 변화는 다음과 같다.

  • 분기 로직이 코드에서 데이터로 이동
  • 조건의 확장은 객체의 확장으로 해결
  • 실행 흐름이 훨씬 단순해짐

복잡성을 제거하고 데이터드리븐으로 변경하면서 조건을 매핑 규칙으로 치환한다.

데이터 드리븐(data driven)

사용자가 이벤트를 발생시켰을때 즉 마우스/키보드로 데이터를 전송 했을때에만 작동하는 것.
이벤트가 발생할 때 까지 자원(대기시간 및 메모리)의 소비를 최소화한다.

- 라우터의 최소 구성 요소

이 구조를 라우팅 관점에서 바라보면, 라우터는 다음 요소들로 구성된다.

  • Target: 현재 상태 (예: action)
  • Table: 상태와 처리 로직의 매핑 테이블 (예: actions)
  • Rule: 매핑 규칙 (예: key 접근 규칙)
  • Trigger: 라우팅이 실행되는 시점
1
const runner = actions[action];

이 한 줄이 상태를 기준으로 처리 대상을 결정하는 가장 단순한 라우터라고 볼 수 있다.


SPA에서의 라우팅

SPA(Single Page Application) 환경에서 페이지 이동이 곧 문서 이동을 의미하지 않는다.

초기 로딩 이후에는 상태 변화에 따라 화면의 일부만 갱신된다.
이 과정에서 라우팅은 어떤 상태에 어떤 화면을 보여줄 것인가를 결정하는 역할을 한다.

라우팅은 복잡한 기술이 아니다.
결국 상태에 따라 무엇을 실행할지 결정하는 문제.

- History 기반 라우팅

Browser History Mode는 HTML5 History API를 기반으로 URL을 관리하는 방식.
history.pushState를 통해 URL을 변경하되, 페이지를 새로 로드하지 않고 상태만 갱신한다.

1
2
3
4
5
window.history.pushState(
  { data: "some data" },
  "Some history entry title",
  "/some-path"
);

브라우저의 뒤로 가기 / 앞으로 가기 동작은 popstate 이벤트를 통해 감지할 수 있다.

1
2
3
window.onpopstate = () => {
  appDiv.innerHTML = routes[window.location.pathname];
};

URL이 /some-path 형태로 깔끔하지만, 브라우저가 해당 경로로 직접 접근할 경우 서버가 이를 처리할 수 있어야 한다.
따라서 Browser History Mode를 사용할 때는 모든 경로 요청을 SPA의 진입 지점으로 돌려주는 서버 설정이 필요하다.

- Hash 기반 라우팅

Hash History Mode는 URL의 해시(/#)를 사용해 상태를 표현하는 방식이다.

해시 값은 window.location.hash를 통해 확인할 수 있으며, 해시가 변경될 때마다 hashchange 이벤트가 발생한다.

1
2
3
window.addEventListener("hashchange", () => {
  appDiv.innerHTML = routes[window.location.hash.replace("#", "")];
});

이 방식은 브라우저가 서버에 새로운 경로를 요청하지 않기 때문에 별도의 서버 설정 없이도 동작한다.
정적 페이지나 서버 제어가 어려운 환경에서는 Hash History Mode만으로도 충분한 라우팅을 구현할 수 있다.


이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.