『Hypermedia Systems』
Carson Gross et al., “Hypermedia Systems”, hypermedia.systems, 2023
Hypermedia Concepts
Hypermedia: A Reintroduction
- 하이퍼미디어는 좋은 아이디어였고, 지금도 그렇다. 수십 억명의 사람들이 매일 하이퍼미디어 기반 시스템을 사용한다.
- 하지만 요즘에는 하이퍼미디어라는 주제를 논하지 않는다. 대부분의 웹 개발자들이 JSON API를 사용해 노드 서버와 상호작용하는 리액트 애플리케이션을 만들면서 커리어를 시작한다. 이들은 시스템으로서 하이퍼미디어는 전혀 배운 적이 없을 수도 있다. 이는 비극이다.
- 오늘 날 가장 인기있는 하이퍼미디어인 HTML은 점점 레거시 마크업 언어로 여겨지고 있다. (자바스크립트 기반 웹 앱에서 어쩔 수 없이 사용해야 하는 어색한 언어라는 느낌) 하지만 HTML이 브라우저에 존재하는 이상, 이것을 사용해야 한다. 하이퍼미디어는 레거시 기술이 아니다.
- 하이퍼미디어란 무엇인가?
- 하이퍼미디어는 텍스트와 같은 미디어(매체)를 의미한다. 미디어에 포함된 하이퍼링크를 통해 한 위치에서 다른 위치로 비선현 분기할 수 있다.
- 하이퍼링크는 하이퍼미디어 컨트롤의 대표적인 예다. 하이퍼미디어 컨트롤이란 어떤 (주로 원격 서버와의) 상호작용에 대한 정보를 자기설명적으로 인코딩하는 하이퍼미디어 요소로, 하이퍼미디어를 다른 미디어와 차별화하는 핵심적인 요소다.
- 하이퍼텍스트는 하이퍼미디어의 하위 범주다. HTML과 같은 하이퍼텍스트는 하이퍼미디어 시스템을 작동하게 만드는 여러 기술 HTTP 등 네트워크 프로토콜과 비디오, 이미지 등 미디어 유형, API 서버, 브라우저와 함께 동작한다.
- 하이퍼미디어의 역사
- Vannevar Bush의 『As We May Think』를 현대 하이퍼미디어의 출발점으로 볼 수 있음. 여기서 Bush는 메멕스를 소개한다. 실제로 구현된 적은 없지만, 이후 하이퍼미디어에 큰 영감을 제공했다.
- 하이퍼미디어와 하이퍼텍스트라는 용어는 FRESS를 만든 Ted Nelson이 만들었다.
- Douglas Engelbart는 메멕스를 구현하기 위해 노력했다. 1968년 그는 원격 편집, 영상 및 음성 채팅, 통합 윈도우 시스템, 하이퍼텍스트 등을 개발해 시연했다.
- 이후 Tim Berners-Lee가 첫 웹사이트를 공개했다. 연구자들과 연구 결과물을 공유하고자 월드 와이드 웹을 만든 것. 그리고 1994년 W3C가 설립됐다.
- Roy Fielding은 2000년 박사 학위 논문 Architectural Styles and the Design of Network-based Software Architectures에서 새로운 네트워킹 아키텍처를 제안했다.
- HTML은 세계에서 가장 성공한 하이퍼텍스트가 됐다. HTML2.0이 도입됐을 때 웹은 문서 시스템이 아닌 애플리케이션 아키텍처로 전한되었다.
- 하이퍼미디어로서 HTML의 앵커 태그와 폼 태그를 좀 더 자세히 살펴보자: 앵커 태그는 문서에서 문서로, 리소스에서 리소스로 이동하기 위한 방법을 제공하며, 폼 태그는 리소스를 변경할 수 있는 방법을 제공한다. 아주 익숙한 내용이지만, 이 두 가지 하이퍼미디어 컨트롤인 앵커와 폼이 사용자가 일반 HTML로 서버와 상호작용할 수 있는 유일한 방법이라는 사실을 생각해야 한다. 웹은 단 두개의 태그를 통해 사람들에게 엄청난 양의 동적 기능을 제공해왔다. 이는 하이퍼미디어의 힘을 보여주는 강력한 증거다.
- 그럼 하이퍼미디어가 아닌 것은 무엇인가?
- 서버와 상호작용하는 또 다른 방법은 자바스크립트를 사용하는 것이다. 자바스크립트의 fetch API는 HTTP 요청을 발행한다. AJAX 요청은 일반적인 HTTP 요청과 비슷하지만, 브라우저에 의해 무대 뒤에서 실행된다. 오늘날 이 요청에 대한 응답은 대부분 JSON이다.
- JSON 기반 상호작용은 하이퍼미디어를 사용하지 않는다. JSON API는 하이퍼미디어 응답을 반환하지 않으며, 여기에는 하이퍼미디어 컨트롤이 없다. JSON API는 데이터 API이다. 따라서 자바스크립트는 JSON 응답 데이터를 HTML로 변환해야 한다.
- 이 방식은 SPA의 시작이 되었다. 웹 앱은 하이퍼미디어 컨트롤을 사용해 페이지간 탐색을 지원하는 대신, 서버와 순수 데이터를 교환한 다음 단일 페이지 내의 콘텐츠를 업데이트한다. 오늘날 대다수의 SPA는 리액트, 뷰, 앵귤러와 같은 프레임워크로 구축된다. 이들의 방식은 웹 클라이언트에 대한 훨씬 더 정교한 접근 방식을 취하며, 일반적으로 브라우저가 제공하는 기본 하이퍼미디어 인프라를 전혀 사용하지 않는다.
- SPA의 두 가지 핵심 요소는 다음과 같다: 주요 UI를 자바스크립트로 구축, 업데이트한다. 그리고 백엔드는 해당 애플리케이션으로부터 요청을 받는 API이다.
- SPA에는 많이 장점이 있고, 이 아키텍처가 순식간에 세계를 휩쓴 것도 우연이 아니다. 그럼에도 지금 하이퍼미디어를 다시 이야기해야 하는 이유는 무엇인가?
- 하이퍼미디어에도 장점이 있다: (1) 웹 앱을 구축하는 매우 간단한 방식이다. (2) 콘텐츠와 API의 변경에 관대하다. (3) 캐싱과 같은 브라우저의 검증된 기능을 활용할 수 있다.
- 특히 (1), (2)는 최신 모던 웹 개발의 주요 문제를 해결할 수 있다: SPA 인프라는 너무 복잡하며, 이를 관리하기 위한 팀이 필요하다. 애플리케이션의 요구를 맞추기 위해 JSON API의 지속적인 변경이 필요하다.
- 이러한 장점에도 불구하고, 하이퍼미디어가 웹 개발에 다시 돌아오지 못한 데에는 두 가지 이유가 있다. 첫 번째는 하이퍼미디어로서의 HTML의 표현력이 90년대 중반에 출시된 HTML2.0 이후로 거의 변하지 않았다는 점이다. 거의 30년간 HTML에서 서버와 상호작용할 수 있는 새로운 방법이 없었다. 두 번째 이유는, 첫 번째 이유로 인해 상호작용에 대한 사용자의 요구를 HTML이 수용하지 못했다는 점이다.
- SPA가 성공한 것은 HTML이 정교한 사용자 경험을 지원하지 못했기 때문이지, 시스템 아키텍처로서의 SPA가 고유한 우월성을 가졌기 때문이 아니다. HTML에 더 많은 상호작용성을 요구했다면 다른 일이 일어났을 것이다.
- 지난 10년간 몇몇 대안적인 프론트엔드 라이브러리도 등작했다. 아이러니하게도 이들은 자바스크립트로 구현되었다. SPA와 MPA(Web 1.0 방식의 현대적인 이름) 사이에는 지속적인 논쟁이 있었다. MPA는 Fielding이 논문에서 설명한 것과 정확히 같다. 이러한 앱들은 투박한 경향이 있지만 합리적으로 동작한다. Rich Harris는 MPA 스타일과 SPA 스타일의 융합을 제안하기도 했다. 하지만 이런 과도기적 타협은 여전히 만족스럽지 않다.
- 하이퍼미디어 지향 라이브러리는 MAP와 SPA 간의 차이를 극적으로 줄일 수 있다. 높은 사용자 경험을 달성하면서도 하이퍼미디어 접근 방식을 사용할 수 있다. htmx는 하이퍼미디어 지향 라이브러리다.
- htmx는 MPA가 아니다. 권장하지는 않지만, htmx로 SPA를 만들 수 있기 때문이다.따사러 우리는 HDA(Hypermedia-Driven Applicaiton)이라는 용어를 사용한다. MPA와 HDA, SPA를 구분하는 중요한 요소는 페이지 수가 아니라 시스템 아키텍처다.
- htmx는 웹의 하이퍼미디어 시스템을 대체하는 대신, 확장한다. HTML과 다른 아키텍처를 갖춘 하이퍼미디어 시스템이다.
- HDA는 서버와 통신하기 위한 기본 매커니즘으로 하이퍼미디어를 사용하는 웹 애플리케이션이다. htmx의 간단한 예시를 살펴보자:
<button hx-get="/contacts/1" hx-target="#contact-ui"> Fetch Contact </button>
- 이 코드는
/contacts/1
에 GET 요청을 보내#contact-ui
를 대체한다. - 여기에는 자바스크립트가 없다. 대신 선언적 속성을 사용한다.
hx-get
속성은 요소가 클릭되었을 때 GET 요청을 보내도록 지시한다.hx-target
속성은 응답을 받으면 결과 HTML을 가져와서 해당하는 요소에 배치하도록 지시한다. - 이때 서버의 HTTP 응답은 JSON이 아닌 HTML이어야 한다. 위 코드에 대한
/contacts/1
의 응답은 아래와 같다:<details> <div> Contact: HTML Example </div> <div> <a href="mailto:html-example@example.com">Email</a> </div> </details>
- 이 코드는
- 단, 하이퍼미디어가 어울리지 않는 웹 앱도 있다. 온라인 스프레드시트 애플리케이션은 셀이 반응적으로 동작하며 엄청난 양의 업데이트를 일으킬 수 있다. 모든 셀 변경에 하이퍼미디어 스타일의 서버 round-trip을 일으키면 성능 저하를 피할 수 없을 것이다.
Components of a Hypermedia System
- 하이퍼미디어를 하이퍼미디어로 만드는 것은 하이퍼미디어 컨트롤이다. 이를 통해 사용자는 하이퍼미디어 내에서 비선형 명령을 내릴 수 있다. HTML의 경우 링크와 폼을 주로 URL로 표현한다.
- 하이퍼미디어 클라이언트는 특정 하이퍼미디어를 해석하는 소프트웨어다.
- 대표적으로 웹 브라우저는 믿을 수 없을 정도로 정교한 하이퍼미디어 클라이언트다. 너무 정교해서 하이퍼미디어 클라이언트에서 SPA를 실행하기 위한 일종의 크로스 플랫폼 VM으로 여겨지기도 한다.
- 하지만 브라우저가 유일한 하이퍼미디어 클라이언트는 아니다. 우리는 뒤에서 하이퍼뷰를 설명할 것이다.
- 이제 Roy Fielding의 REST 이야기를 해보자:
- Fielding이 논문을 작성할 당시에는 JSON API와 AJAX가 존재하지 않았다는 점을 생각해야 한다. 그는 HTML이 HTTP로 전송되는 초기 웹을 하이퍼미디어 시스템으로서 설명했다. 오늘날 REST라는 용어를 하이퍼미디어가 아닌 JSON 데이터 API에 연관지어 말하는 것은 이상한 일이다. JSON API 대다수가 원래 의미에서 RESTful하지 않으며, 실제로 자연스러운 하이퍼미디어 형식을 사용하지 않기 때문에 RESTful할 수도 없다. REST가 JSON API를 의미한다고 생각하지 말자.
- 개발자의 입장에서 그의 논문 중 가장 중요한 부분은 제약조건 섹션이다. Fielding이 말하는 REST의 제약조건은 아래와 같다:
- 클라이언트-서버 아키텍처다: 그는 WWW의 네트워크 아키텍처를 다른 네트워크 모델과 대조해 설명한다. 오늘날 거의 모든 웹 앱이 이 요구사항을 충족한다는 것은 자명하다.
- 무상태이어야 한다. 즉, 요청에는 응답에 필요한 모든 정보가 포함되어야 한다: 이 관점에서 세션 쿠키는 위반이다. 세션 정보는 일반적으로 여러 웹 서버에 걸쳐 일종의 공유 저장소에 보관된다. 하이퍼미디어 서버를 배포할 때 세션은 추가적인 운영상의 복잡성을 높인다.
- 캐싱을 허용해야 한다: HTTP에는 자체적인 캐싱 매커니즘이 있다.
- uniform interface를 갖춰야 한다: REST에서 가장 혁신적인 부분이다. 균일 인터페이스 제약은 하이퍼미디어의 유연성과 단순성의 원천이므로 깊이 얘기해볼 필요가 있다.
- Fielding은 다음과 같이 설명했다: The central feature that distinguishes the REST architectural style from other network-based styles is its emphasis on a uniform interface between components… In order to obtain a uniform interface, multiple architectural constraints are needed to guide the behavior of components. REST is defined by four interface constraints: identification of resources; manipulation of resources through representations; self-descriptive messages; and, hypermedia as the engine of application state
- 자원식별: RESTful 시스템의 리소스에는 고유 식별자가 있다. 모든 종류의 데이터, 즉, 하이퍼미디어가 참조하는 모든 대상은 리소스다.
- 표현을 통한 리소스 조작: RESTful 시스템에서 리소스의 표현은 클라이언트와 서버 사이에서 전송된다. 이러한 표현은 데이터와 메타데이터(HTTP 메서드, 응답코드 등)를 포함한다.
- 자기기술적 메시지: RESTful 시스템에서 메시지는 자기기술적이다. 구체적인 예를 생각해보자.
/contacts/42
에 HTTP 요청을 보내면 HTML이나 JSON을 응답할 수 있을 것이다.<html lang="en"> <body> <h1>Joe Smith</h1> <div> <div>Email: joe@example.bar</div> <div>Status: Active</div> </div> <p> <a href="/contacts/42/archive">Archive</a> </p> </body> </html>
{ "name": "Joe Smith", "email": "joe@example.org", "status": "Active" }
- 둘의 차이는 뭘까? 가장 눈에 띄는 점은 JSON이 HTML보다 작다는 것이다. Roy Fielding도 이 점에 대해 트레이드 오프라고 언급했다.
- HTML에는 연락처를 아카이브할 수 있는 하이퍼링크가 있다. 이 부분이 중요한데, JSON API를 처리하는 클라이언트가 다른 정보를 얻으려면, 사전에 URL을 알아야 한다는 것이다. JSON 응답만을 보고 클라이언트는 어떤 동작을 취할 수 있을까? 그런 정보를 API 문서로부터 얻거나, 서버 개발자에게 물어볼 수도 있을 것이다. 그러나 그 모든 것이 암시적이며, 응답 밖에 있다는 점이 문제다.
- 반면 하이퍼미디어 응답(HTML)은 클라이언트가 주어진 HTML을 렌더링하는 방법만 알면 된다. 클라이언트가 선택할 수 있는 작업은 HTML 내에 하이퍼미디어 컨트롤로 인코딩된다.
status
필드가 무엇을 의미하는지 알 필요도 없다. 사실 클라이언트는 연락처가 뭔지도 모른다.
- 애플리케이션 상태 엔진으로서의 하이퍼미디어(HATEOAS): 이 제약은 자기기술적 메시지와 밀접하게 연관되어 있다. 앞선 예시에서 액티브 상태인 연락처를 아카이브한다고 생각해보자. 응답은 어떨까?
<html lang="en"> <body> <h1>Joe Smith</h1> <div> <div>Email: joe@example.bar</div> <div>Status: Archived</div> </div> <p> <a href="/contacts/42/unarchive">Unarchive</a> </p> </body> </html>
{ "name": "Joe Smith", "email": "joe@example.org", "status": "Archived" }
- HTML 응답에는 앞선 예시와 달리 더 이상 연락처를 아카이브할 수 있는 하이퍼링크가 없다. 대신 아카이브 취소 작업이 제공된다.
- 오늘날 대부분의 SPA 프론트엔드에서 이 연락처 정보는 자바스크립트 객체로 표현되어 메모리에 저장되는 반면, 페이지에 대한 데이터는 브라우저의 DOM으로 표현된다. 그리고 DOM은 자바스크립트 모델의 변경에 반응하도록 구현된다. 이런 방식은 확실히 HATEOAS가 아니다. 오히려 자바스크립트 모델을 애플리케이션 상태 엔진으로 사용하고, 그 모델을 브라우저와 동기화하는 것에 가깝다.
- 반면 HTML을 사용하면 하이퍼미디어는 실제로 애플리케이션의 상태 엔진이 된다. 클라이언트에는 추가적인 모델이 없으며, 모든 상태는 하이퍼미디어(여기에서는 HTML)로 직접 표현된다. 서버의 상태가 변경되면 클라이언트로 다시 전송되는 표현(HTML)에 반영된다.
- 애플리케이션에 새 기능이 추가되는 경우 하이퍼미디어의 유연성은 더욱 빛난다. 만약 메시지 기능을 추가하고 싶다면 간단히 HTML 응답에 메시지를 보낼 수 있는 하이퍼링크를 추가하기만 하면 된다. JSON을 응답한다면 API 문서를 작성해야 할 것이다. 여기서 드러나는 또 다른 사실은, 이러한 유연성 덕분에 하이퍼미디어에는 JSON API와 같은 버전 관리 문제가 일어나지 않는다는 점이다.
- layered system이다: RESTful 시스템이 계층화되어서 여러 클라이언트가 최종적인 진실의 원천에 이르는 데 여러 서버가 중개자 역할을 할 수 있어야 한다는 것이다. 요즘에는 CDN이 이 역할을 한다.
- 선택적으로 Code-On-Demand, 즉 스크립팅이 가능해야 한다: 이건 선택 사항이다. 확장성이 높아지지만 가시성이 낮아진다.
A Web 1.0 Application
- 웹 1.0 스타일로 Contact.app이라는 연락처 관리 웹 앱을 만들어본다.
- Flask 서버가 템플릿 엔진을 통해 HTML을 만들어서 응답. 연락처 CRUD 구현…
- 웹 1.0 앱은 투박하다. 페이지를 이동할 때마다 전체 화면을 다시 렌더링해야 하기 때문에 플리킹이 일어나고, 스크롤 위치도 초기화 되어 버린다. 현 시점에서 우리가 만든 Contact.app은 현대적으로 느껴지지 않는다. 이 웹 앱을 인터랙티브하기 위해서는 자바스크립트와 JSON API가 필요할까? 노노 그렇지 않다. 이제 htmx로 이 웹 앱을 개선해보자.
Hypermedia-Driven Web Applications With Htmx
Extending HTML As Hypermedia
- 앞서 만든 웹 1.0 스타일 애플리케이션에는 크게 두 가지 문제가 있다.
- 사용자 경험 관점에서 페이지를 이동할 때마다 눈에 띄게 새로고침이 일어난다.
- 모든 업데이트가 POST 요청으로 이뤄진다.
- htmx는 사용자에게 자바스크립트 작성을 요구하지 않고 HTML을 확장한다.
- 모든 요소가 HTTP 요청을 발행하는 하이퍼미디어 컨트롤로 동작한다:
hx-(get|post|put|patch|delete)
속성을 사용하면 “사용자가 이 요소를 클릭했을 때 지정된 유형의 HTTP 요청을 발행한다”고 선언할 수 있다. - 하이퍼링크 클릭 뿐만 아니라 모든 이벤트가 HTTP 요청을 트리거한다: 클릭 외에 change, submit 등의 이벤트로 HTTP 요청을 발행하고 싶을 수 있다. 이때는
hx-trigger
속성을 사용하면 된다. 만약 상위 요소에서 발생한 이벤트를 수신하고 싶다면 값에from
을 추가하면 된다. - HTML에서 누락된 PUT, PATCH, DELETE를 허용한다: 앞서 설명한
hx-(get|post|put|patch|delete)
로 해결된다. - 전체 페이지를 교체하는 대신 일부 요소만 교체한다:
hx-target
속성을 사용하면 하이퍼미디어 콘텐츠를 삽입할 요소를 지정할 수 있다. 값으로 CSS 셀렉터를 지정하면 응답으로 받은 HTML이 해당 요소의 하위 요소로 삽입된다. 만약 하위 요소로 삽입하는 대신 교체하고 싶다면hx-swap
속성을 사용하면 된다.
- 모든 요소가 HTTP 요청을 발행하는 하이퍼미디어 컨트롤로 동작한다:
- 그 외
hx-boost
,hx-push-url
등 속성에 대한 설명…
이 문서를 인용한 문서
- 소프트웨어 공학
- htmx
- 리액트 서버 컴포넌트
-
리액트 서버 컴포넌트는 『Hypermedia Systems』의 저자들이 제안하는 방법과 매우 유사해 보인다.
-
- Goodbye 2024
-
📖 Carson Gross et al., 『Hypermedia Systems』, 2023.
-