Halal Booking은 기존에 React(ClojureScript), CoffeeScript 및 비간섭형 JavaScript로 구성된 복잡한 프런트엔드를 가진 대규모 여행 웹사이트였습니다. Hotwire로의 마이그레이션 과정에서, Turbo Drive나 전체 페이지 모핑과 같은 기능은 기존 JavaScript의 전체 페이지 라이프사이클 가정 때문에 적용하기 어려웠습니다. 그러나 Hotwire의 핵심 기술인 Turbo Frames, Turbo Streams, 그리고 Stimulus는 기존 웹사이트에 대한 가정을 거의 하지 않아 레거시 환경에 매우 적합했습니다.
Hotwire의 레거시 시스템 적용 사례
-
간단한 콘텐츠 로딩: 초기 로드 후 추가 콘텐츠를 로드하는 일반적인 패턴은 Turbo Frame을 통해 쉽게 구현되었습니다. 이는 페이지의 특정 부분을 Turbo Frame으로 지정하고 해당 콘텐츠를 로드하는 방식으로, SPA(Single Page Application)와 유사한 경험을 제공합니다.
-
로그인/회원가입 플로우: React 컴포넌트 시리즈로 구현되었던 로그인/회원가입 플로우는 단순히 HTML 폼과 링크로 구성된 독립적인 페이지들을 모달 내 Turbo Frame으로 감싸는 방식으로 마이그레이션되었습니다.
-
무한 스크롤 및 품절 상품 처리:
- 기본 무한 스크롤: 첫 페이지를 로드하는 Turbo Frame 내부에 다음 페이지를 위한
lazy loadedTurbo Frame을 중첩하여 구현했습니다. 사용자가 스크롤하여 뷰포트에 진입하면 자동으로 콘텐츠가 로드됩니다. - 품절 상품 처리: 동적 가격 책정 및 빠른 재고 변동으로 인해 캐싱이 어려운 여행 웹사이트의 특성을 고려하여, 백엔드에서 품절 상품을
turbo_stream_append액션으로 숨겨진div에 추가하고, 사용 가능한 상품이 모두 소진되면 커스텀turbo_stream_pop액션을 통해 숨겨진div에서 품절 상품을 꺼내 표시하는 방식을 사용했습니다. 이 방식은 프런트엔드에 로직을 두지 않고 백엔드에서 렌더링 및 로직을 모두 처리하여 Hotwire의 이점을 극대화했습니다.
- 기본 무한 스크롤: 첫 페이지를 로드하는 Turbo Frame 내부에 다음 페이지를 위한
복잡성 관리 및 아키텍처 원칙
Hotwire를 통한 마이그레이션의 핵심은 ‘복잡성의 원천에 최적화’하는 것이었습니다. Halal Booking의 경우, 콘텐츠의 소화 및 올바른 위치에 표시하는 복잡성은 전적으로 백엔드에 있었습니다. Hotwire는 로직을 백엔드로 이동시켜 이러한 복잡성을 근원적으로 해결하고 코드량을 줄이는 데 기여했습니다. 프런트엔드는 최소한의 가정만을 하는 저수준 도구로 기능하며, 백엔드에서 생성된 HTML을 렌더링하는 역할에 집중했습니다.
지도 검색의 절충안
지도 검색과 같이 리액티브 스타일이 더 적합한 복잡한 기능에서는 약간의 절충이 필요했습니다. 지도 주변, 속성 목록, 각 속성 주변에 Stimulus 컨트롤러를 사용하여, 지도 팬/줌 이벤트 시 보이는 ID 목록을 프런트엔드에서 관리하고, 누락된 항목만 서버에 요청하여 병합하는 방식을 사용했습니다. 이는 여전히 백엔드 렌더링 및 순서 제어를 유지했지만, 일부 프런트엔드 로직이 증가했습니다. 하지만 이는 전체 기술 스택의 단순성을 유지하기 위한 전략적인 결정이었습니다.