TL;DR
- Datastar는 서버 렌더링 다중 페이지 앱(MPA)에서 페이지를 상태 변경 때마다 다시 렌더링해 서버 전송 이벤트(SSE)로 전달하는 방식이며, 복잡한 앱에서는 설정 부담이 크지 않다는 관점임.
- 초기 페이지 로드 시 SSE 연결을 열고, 백엔드 상태가 바뀌면 전체 페이지를 다시 렌더링해 클라이언트에 전달함.
- 사용자 동작은 데이터베이스를 갱신하는 POST 요청으로 처리하고, POST 핸들러는 리디렉션이나 HTML 대신 빈 204 응답을 반환함.
- 서버에서 다시 계산하지 않을 상태는 브라우저 탭별 서버 상태에 보관하고, 네트워크 응답을 기다리지 않아야 하는 입력 상태는 Datastar 시그널로 관리함.
- Datastar는 백엔드 구성 요소와 빠른 렌더링 함수가 필요하지만, htmx는 표준 요청·응답 방식인 대신 갱신할 HTML 조각과 삽입 위치를 요청 핸들러에서 직접 지정해야 함.
Datastar를 바라보는 관점
- 앞서 쓴 Understanding htmx에서는 htmx의 개념과 주요 절충점, 사용할 때와 사용하지 않을 때를 설명했으며, 이 글은 Datastar를 다루는 후속 글임.
- 두 글은 도구를 바라보는 개인적인 관점을 설명하며, 다른 사람이 이 관점에 동의하지 않더라도 사과할 생각은 없음.
- 만드는 웹 앱에는 보통 협업이나 실시간 기능이 없지만, 이런 일반적인 앱에도 Datastar가 괜찮은 선택이라고 봄.
- htmx와 Datastar는 둘 다 React 같은 도구 대신 서버 측 렌더링을 사용하는 도구임. 단일 페이지 앱(SPA)으로 나아가기보다, jQuery 이전의 얇은 클라이언트 웹 개발 방식을 확장하는 접근임.
- 두 도구는 이 구상을 구현하는 방식이 다름.
Datastar의 페이지 상태 모델
다중 페이지 앱(MPA)을 만들고, 각 페이지를 하나의 리소스로 취급하며, 그 리소스의 현재 상태를 계속 전달하는 스트림을 열어 둠.
- 2005년의 다중 페이지 앱(MPA)을 떠올릴 수 있음. 테이퍼를 위한 소셜 네트워크의 각 페이지에는 페이지용 HTML을 반환하는 GET 요청 핸들러와, 작업을 수행한 뒤 해당 HTML 엔드포인트로 리디렉션하는 여러 POST 요청 핸들러가 있음.
- 좋아요 버튼을 일반 HTML 폼으로 구현하면 페이지 전체가 새로고침될 수 있으며, 이때 다음 문제가 생길 수 있음.
- 피드의 모든 게시물을 다시 가져와야 함.
- 다시 가져온 게시물이 이전과 다를 수 있음.
- 사용자의 스크롤 위치가 사라질 수 있음.
- 게시글을 작성하던 중이었다면 초안이 사라질 수 있음.
Datastar의 요청과 렌더링 흐름
- 최초 페이지 로드에서 장기 실행 서버 전송 이벤트(SSE) 연결을 엶. 데이터베이스 트랜잭션 커밋 등 백엔드 상태가 바뀔 때마다 전체 페이지를 다시 렌더링해 SSE 연결을 통해 클라이언트로 전달함. 브라우저를 실제로 새로고침하지 않고 클라이언트에 페이지 새로고침과 비슷한 갱신을 전달하는 방식임.
- 사용자가 게시물에 좋아요를 누르는 등 동작을 수행하면 Datastar가 데이터베이스를 갱신하는 POST 요청 핸들러로 비동기 요청(Ajax)을 보냄. SSE 연결이 다시 렌더링을 유발하므로 POST 핸들러는 리디렉션하거나 HTML을 반환하지 않고 빈 204 응답만 반환함.
- 다시 계산하고 싶지 않은 페이지 상태는 브라우저 탭 하나에 고유한 식별자를 키로 삼아 서버 측 ‘탭 상태’에 저장할 수 있음.
- 예를 들어 페이지 로드 시 동작 또는 POST 요청을 실행해 추천 게시물을 계산하고 탭 상태에 저장할 수 있음.
- GET 요청 핸들러는 추천 게시물을 계산하지 않고 탭 상태를 읽음. 탭 상태가 아직 채워지지 않았다면 로딩 표시를 보여 줌.
- 서버 왕복을 기다리지 않고 빠르게 다시 렌더링해야 하는 상호작용은 Datastar의 프런트엔드 전용 상태 처리 방식인 ‘시그널’을 갱신할 수 있음.
- 폼 입력값을 시그널에 저장하는 것이 흔한 사례임. 텍스트 필드에 입력할 때 네트워크 응답을 기다리지 않고 글자가 화면에 나타나야 함.
백엔드 구조와 htmx의 차이
- 애플리케이션 코드는 2005년식 MPA와 같은 구조를 유지함. 주요 차이는 POST 핸들러가 303 대신 204를 반환하고, 모든 폼 필드를 시그널에 연결하도록 설정한다는 점임.
- 전체 페이지를 반환하는 단일 렌더링 엔드포인트 또는 함수를 유지할 수 있어, 페이지가 상태의 함수로 렌더링되는 구조를 활용하면서 SSE로 풍부한 상호작용을 구현함.
- 비용은 백엔드에 구성 요소가 더 많이 필요하다는 점임. 코드베이스 설정에 더 많은 작업이 들고 실수할 여지도 늘어남.
- 페이지 렌더링 함수는 여러 차례 호출되므로 빨라야 함. 이를 위해 구조를 바꿔야 할 수 있으며, 앞서 든 예시처럼 페이지 로드 시 동작을 실행해 추천 게시물을 계산하는 방식이 이에 해당함.
- 반면 htmx는 백엔드 아키텍처를 전면적으로 바꾸려 하지 않으며, 일반적으로 SSE 대신 표준 요청·응답 방식을 사용함.
- 그 대신 애플리케이션 코드에서 더 많은 일을 처리해야 함. 버튼을 누르면 htmx가 POST 요청을 보내고, 백엔드 요청 핸들러는 어떤 HTML 조각을 다시 렌더링할지와 해당 조각을 문서 객체 모델(DOM)의 어디에 삽입할지를 알아야 함.
- 이 방식은 명령형에 가까우며, 페이지 전체를 단일 함수로 렌더링하는 단순한 구조를 유지하기 어려움.
Datastar를 선택할 상황
- 언급한 Datastar의 단점은 특히 배선 작업을 대신 설정해 주는 라이브러리를 사용할 경우 큰 문제는 아니라고 봄.
- 일반 HTML 폼 제출 후 리디렉션만으로 충분한 아주 작은 앱을 만든다면 Datastar를 쓰지 않을 가능성이 가장 큼.
- htmx를 고려할 만큼 복잡한 앱이라면 Datastar 설정 오버헤드는 무시할 만하다고 보므로, htmx를 다시 선택할 상황은 떠오르지 않음.
댓글 (0)
로그인하면 이 기사에 내 생각을 남길 수 있어요