“자바스크립트 없는 동적 HTML” HTMX의 이해와 기본 활용법

HTMX는 자바스크립트 대신 확장된 HTML 구문을 사용해 상호작용성을 달성한다. HTMX는 마크업에서 바로 HTTP 상호작용을 제공하며, 자바스크립트에 의존하지 않고도 다른 많은 상호작용 요구사항을 지원한다. 향후 웹 프론트 엔드의 작동 방식에 영향을 미칠 잠재력을 지닌 흥미로운 개념이다. HTMX가 어떻게 사용되는지, 매력은 무엇인지를 알아보자. 

HTMX란

HTMX는 꽤 오래전에 나왔지만 그동안 활동이 다소 뜸했던 프로젝트다. 최근 깃허브 액셀러레이터(GitHub Accelerator)에 발탁된 만큼 분위기가 바뀔 가능성이 높다. 기본적인 개념은 상용구 자바스크립트-HTML 상호작용이 필요한 일반적인 상황에서 자바스크립트 없이 HTML 구문만 사용한다는 것이다. 많은 상호작용이 HTMX를 통해 선언적이 된다. 여기까지만 들어도 귀가 솔깃하다. 웹 개발자라면 누구나 상용구 사례가 많다는 것을 알고 있다. HTMX를 만든 카슨 그로스는 “하이퍼텍스트로 HTML을 완성해 더 진보적인 현대 웹 애플리케이션을 위한 경쟁력 있는 대안이 되도록 표현력을 높이는 것이 목표다”라고 말했다. 

HTMX에 대해 대략적인 감을 잡기 위해 이 데모를 보자. 기본적으로 버튼을 클릭해 사용자 객체의 필드를 편집하는 예제다. 데이터는 백엔드 엔드포인트로 들어간다(PUT). <화면 1>을 보면 Show를 클릭한 이후 하단 프레임의 네트워크 상호작용을 볼 수 있다. 

<화면 1> HTMX 폼 데모 ⓒ IDG

일반적으로 어느 프레임워크를 사용하든 이런 작업을 하려면 자바스크립트가 필요하다. 하지만 HTMX는 <예시 1>에서 볼 수 있듯이 이 상호작용을 표시 UI를 위한 마크업과 편집 UI를 위한 마크업, 2개의 마크업 덩어리로 바꾼다. 

<예시 1> HTMX 사용자 업데이트 

<div hx-target=”this” hx-swap=”outerHTML”>
    <div><label>First Name</label>: Joe</div>
    <div><label>Last Name</label>: Blow</div>
    <div><label>Email</label>: [email protected]</div>
    <button hx-get=”/contact/1/edit” class=”btn btn-primary”>
    Click To Edit
    </button>
</div>
<!– The edit: –>
<form hx-put=”/contact/1″ hx-target=”this” hx-swap=”outerHTML”>
  <div>
    <label>First Name</label>
    <input type=”text” name=”firstName” value=”Joe”>
  </div>
  <div class=”form-group”>
    <label>Last Name</label>
    <input type=”text” name=”lastName” value=”Blow”>
  </div>
  <div class=”form-group”>
    <label>Email Address</label>
    <input type=”email” name=”email” value=”[email protected]”>
  </div>
  <button class=”btn”>Submit</button>
  <button class=”btn” hx-get=”/contact/1″>Cancel</button>
</form>
<예시 1>을 보면 어떤 동작이 이뤄지는지 쉽게 알 수 있다. hx-swap 속성은 편집되기 전 div를 위한 HTML을 제공하고, outerHTML은 이것이 프레임워크에 내부의 동적 콘텐츠와 어떻게 관련되는지 알려준다. 편집 가능한 버전은 PUT HTML 메서드와 사용할 엔드포인트를 식별하는 x-put 속성이 포함된 양식(form) 요소로 구현된다. 

여기서 HTMX는 자바스크립트를 전혀 사용하지 않고 이 “swap”과 그 이후의 PUT을 어떻게 구현했을까하는가? 답은 쉽다. 편집 마크업에 HTML의 서버 측 렌더링을 사용하고, 양식 마샬링을 프레임워크로 추상화하는 것이다. 배후에서는 여전히 자바스크립트가 실행된다. 사실상 우리가 보는 것은 전체 페이지 대신 세그먼트만 로드할 수 있고 Ajax 요청을 제출할 수 있는 더 세분화된 HTML 구문이다. 이는 DRY 원칙의 흥미로운 실제 예시다. 리액트(React) 등을 사용해도 한 양식에서 다른 양식으로 정보를 섞을 때는 상용구 코드를 일정 정도 써야 한다. HTMX는 이를 완전히 제거한 것은 아니지만, 그 작업을 서버로 옮겼다.

서버 측 HTMX 

이제 서버 측을 보자. 그로스는 “HTMX는 백엔드를 가리지 않는다. HTML만 사용하면 어느 백엔드를 쓰든 관계없다”라고 말했다. 이런 장점은 HTMX를 사용하는 서버 측 기술이 다양하기 때문이다. 어떤 식으로 작동하는지 알아보기 위해 익스프레스(Express)와 함께 퍼그(Pug) HTML 템플릿 엔진을 사용하는 TODO 예제를 보자. 이 예제는 일반적인 TODO 애플리케이션이다. 

우선, 기존 to-do 항목은 다음 명령을 사용한 익스프레스의 출력이다. 

res.render(‘index’, { todos: filteredTodos, filter, itemsLeft: getItemsLeft() });
이 명령은 메모리 내 to-do 컬렉션을 사용하고, HTMX 상호작용을 이끄는 특수한 hx- 속성을 포함한다는 점을 제외하면 일반적인 형식의 퍼그 템플릿을 사용해 렌더링한다. 예를 들어 새 to-do를 POST하는 양식은 <예시 2>와 같다. 

<예시 2> HTMX 속성을 사용한 양식 POST

form(hx-post=”/todos”, hx-target=”#todo-list”, hx-swap=”afterbegin”, _=”on htmx:afterOnLoad set #txtTodo.value to ””)
  input#txtTodo.new-todo(name=”todo”,placeholder=’What needs to be done?’, autofocus=”)
afterbegin 속성이 새 콘텐츠를 목록의 맞는 위치에 어떻게 넣는지는 여기서 볼 수 있다. on htmx 스크립트는 일종의 간소화된 스크립팅 언어인 하이퍼스크립트다. HTMX와 함께 자주 쓰이지만, HTMX의 일부이거나 HTMX를 사용하기 위해 필수적인 것은 아니다. 여기서 on htmx는 새 to-do가 만들어진 후 입력 양식의 값 설정을 처리하는 역할을 한다. <예시 3>에서는 to-do 편집을 위한 퍼그 템플릿을 볼 수 있다. 

<예시 3> 퍼그의 서버 측 템플릿 편집

form(hx-post=”/todos/update/” + todo.id)
  input.edit(type=”text”, name=”name”,value=todo.name)
<예시 3>에서 마크업은 편집된 to-do에 대한 JSON을 어디로 보낼지 나타내기 위해 hx-post 속성을 사용한다. 이 예제의 핵심은 앞서 언급한 부분, 즉 다양한 상호작용을 위해 프론트 엔드에서 필요로 하는 화면의 다양한 부분을 채우기 위한 적절한 크기의 HTML(HTMX 태그로 데코레이션됨)을 제공하는 작업을 서버가 담당한다는 점이다. HTMX 클라이언트는 속성을 기반으로 이를 적절한 위치에 배치하고, 서비스에서 소비할 수 있도록 적절한 데이터를 전송하는 부분도 처리한다. 

데이터 수신을 담당하는 엔드포인트는 일반적인 엔드포인트처럼 작동할 수 있는데, 차이점은 필요한 HTMX가 응답이 되어야 한다는 것이다. 예를 들어 <예시 4>에서 익스프레스 서버가 새 to-do를 생성하기 위해 POST를 어떻게 처리하는지 볼 수 있다. 

<예시 4> to-do 생성 처리 

app.post(‘/todos’, (req, res) => {
  const { todo } = req.body;
  const newTodo = { 
    id: uuid(),
    name: todo, 
    done: false 
  };
  todos.push(newTodo);
  let template = pug.compileFile(‘views/includes/todo-item.pug’);
  let markup = template({ todo: newTodo});
  template = pug.compileFile(‘views/includes/item-count.pug’);
  markup  += template({ itemsLeft: getItemsLeft()});
  res.send(markup);
});
<예시 4>는 일반적인 POST 본문 핸들러로, 양식 데이터에서 값을 가져와 새 비즈니스 객체를 생성한다(newTodo). 그런 다음 이 값을 사용해서 퍼그 템플릿을 채우고 이를 클라이언트로 돌려보내 프론트 엔드의 Todo 목록에 삽입한다. 이외 또다른 서버 측 기술도 있다. 예를 들어 자바 환경에서는 타임리프(Thymeleaf) 및 스프링 부트(Spring Boot) 조합과 함께 HTMX를 사용하고, 파이썬 환경에서는 장고(Django) 및 스프링 부트 조합으로 사용할 수 있다.

HTMX를 사용한 클라이언트 측 템플릿 

HTMX가 지원하는 또다른 시나리오는 클라이언트 측 템플릿을 사용하는 것이다. 이는 클라이언트에서 실행되고 서버로부터 JSON을 받아 마크업 해석을 수행하는 계층이다. 필자는 그로스에게 RESTful 서비스를 JSON과 함께 사용하는 방법에 대해 물었는데, 그로스는 클라이언트 측 템플릿을 사용하면 가능하지만 REST에 대한 일반적인 오해를 주의해야 한다고 말했다. 그렇다면 역으로, 기본 양식 인코딩 대신 JSON을 서버에 제출하려면 어떻게 해야 할까? 여기에는 확장 기능인 JSON-ENC가 있다. 

결론 

HTMX는 여러 가지 점에서 매우 흥미롭다. 결론은 이 개념이 프로젝트 자체 못지않게 유익하다는 것이다. 점점 성숙해지면서 HTMX가 지금과 똑같이 작동하지 않을 수 있지만, 유익한 영향은 이미 입증됐다. 가장 매력적인 부분은 일반적으로 fatch() 또는 이와 비슷한 것을 사용하는 매우 보편적인 Ajax 스타일의 온갖 다양한 요청을 HTML 속성 하나로만 처리한다는 개념이다. 더 단순하고 깔끔하며 모든 요소를 한 곳에 두는 방식이다. 마크업이 무엇을 하는지가 매우 명확하다. 

필자는 서버 측 마크업 생성에 대해서는 더 양면적인 생각을 갖고 있다. 개발자는 이미 이런 목적으로 JSON을 다루는 데 매우 익숙하다. 마크업을 가져오는 것은 클라이언트 생성에서 한 단계를 추가하는 것일 뿐이다. 그동안 수많은 서버 측 접근 방식이 등장했고 이런 방식은 항상 HTML, 자바스크립트, CSS라는 강력한 3요소를 잘 뒤로 숨기는 것처럼 보였지만 결국은 모두 실패했다. 반면 HTMX는 다를 수 있다. 큰 추가 흔들리고 있다. 

물론 서버를 익숙한 JSON 이미터(emitter)로 남겨두는 클라이언트 측 템플릿 옵션도 있다. 필자는 이 방식이 대규모 소프트웨어 프로젝트에서 어떻게 작동할지 상상해봤다. 대규모 프로젝트에서 전체적인 복잡성을 낮춰줄까? 그로스는 이런 복잡성에 대해 나름의 생각이 갖고 있고, HTMX의 설계를 보면 이것이 반영된 것을 알 수 있다. 이 기술은 웹 애플리케이션을 위한 상태 메커니즘으로써 하이퍼텍스트로 돌아가서 이런저런 일을 단순화하는 데 목표를 둔다. 이 예제는 개념이 실제로 어떻게 작동하는지 보여준다. JSON을 프로토콜로 사용한다는 것은 곧 클라이언트를 더 스마트하고 더 복잡하게 만들고, 아키텍처를 덜 자기 설명적으로 만드는 것을 의미한다. 

만약 이런 이상이 실제로 구현된다면, 기반 언어인 HTML을 확장해 Ajax와 같은 최신 요구사항을 실제로 처리함으로써 내재된 복잡성을 피하고 더 단순한 시대로 돌아갈 수 있다. 마크업은 다시 한 번 중앙 데이터 설명자가 되어 UI는 물론 오가는 데이터도 충분히 설명할 수 있게 될 것이다.

출처 : https://www.itworld.co.kr/topnews/308707

문제가 될 시 삭제하겠습니다.

댓글 없음:

참고: 블로그의 회원만 댓글을 작성할 수 있습니다.

Powered by Blogger.