HTMX 와 HTML Response 사용의 이유 (feat. HATEOAS)

식빵·2024년 6월 8일
0

thymeleaf-and-htmx

목록 보기
1/1

🍀 SPA 에 반기를 들다


오늘날 SPA (Single Page Application) 가 프론트엔드 시장을 장악하면서
사실상 서버단에서 html 을 완성해서 주는 일이 많이 줄었습니다.

물론 현재도 많은 곳에서 MPA(Multi Page Application) 를 사용하지만,
(제 기준에서는) 점점 SPA 가 그 자리를 대체하려는 움직임이 보입니다.

그런데 이에 반기(?)를 들 듯 HTMX 라는 것이 나왔습니다.
HTMX 는 단순하게 말하면 javascript Frontend library 입니다.

이미 SPA 에 의한 기능이 넘치다 못해 감당이 안될 정도로 폭발하는 이 상황에
왜 htmx 라는 라이브러리 하나 더 나왔다고 사람들이 이렇게까지 관심을 갖을까요?




🍀 HTMX


정의

HTMXhx-<동사> 형태의 속성(attribute)html tag 에 줘서,
javascript 로 작성해야 했던...

  • 서버와의 비동기 통신 코드,
  • 서버의 응답을 HTML 의 부분 업데이트 코드

...를 줄여 주는 javascript frontend library 입니다.



몇가지 특징들

  1. 위에서 말한 서버와 비동기 통신은 단순한 단건 http 요청뿐만 아니라,
    websocket, sse(server side event) 통신도 포함됩니다.

  2. css transient 도 지원합니다.

  3. 한가지 주의할 점이 있는데 HTMX 요청을 받은 서버는
    반환하는 컨텐츠 타입이 HTML 이어야 한다는 점입니다.
    (이 이유는 Hypermedia System 목차에서 설명하겠습니다)



도입 효과

위와 같이 html 에 hx-* 속성만 몇개 붙여주고, 서버는 그에 맞게 HTML 을
반환하는 API 를 만들면 SPA 와 비슷한 효과를 주는 페이지 구현이 가능해집니다.

이러한 특징 덕분에 얻을 수 있는 좋은 효과들이 있습니다.

  • SPA 의 복잡한 의존성에 의한 무거운 라이브러리 사용을 방지할 수 있습니다.
    (참고로 htmx 라이브러리는 어떤 의존성도 없으며, 크기가 17 kb 밖에 안됩니다)
  • 빠르게 변하는 SPA 관련 지식을 배워야 되는 부담이 많이 줄여줍니다.
  • Backend 에서 HTML 을 반환해야 되는데, 이는 Template Engine 을 통한
    Server Side Rendering (SSR) 을 유도하게 됩니다.
  • SSR 에 의해서 frontend 에서 작성해야 됐던 복잡한 로직들이 줄어들게 됩니다.
  • SSR 의 장점들도 몇가지 얻을 수 있습니다.
    • Seo 최적화, Client 단의 화면 로딩 시간 단축 등
  • htmx 는 프론트엔드의 많은 작업들을 백엔드로 가져오는 효과를 줍니다.
    덕분에 기존 Backend 개발자들 FullStack 개발이 더 쉬워지게 됩니다.
    • jsp, thymeleaf 으로 화면구현을 해온 backend 개발자에게는 희소식이죠. (저 포함)




🙄 JSON 말고 왜 HTML 을 반환할까?


글 읽는 게 힘드신 분들을 위해

이번 목차는 사실상 REST 스타일의 API 에 대한 설명이 주입니다.
그리고 REST 스타일의 구현 방법을 잘 알고 있다면 굳이 이 목차를 읽으실 필요도 없습니다.
하지만 REST 를 잘 모르겠고, 글을 읽는 것도 싫으신 분들은 이 영상 을 보고 넘어가시면 됩니다.
이 영상을 다보고 나서 HTML 반환의 이유는 스스로 짐작하실 수 있게 됩니다.



짧은 답변

결론부터 말하겠습니다.
HTML 반환을 하는 이유는 REST API 를 구현하기 위한 기본 규칙,
특히 HATEOAS 를 지키기 위함입니다.
.

HATEOAS 는 서버의 상태와 관련된 조회(또는 처리) 동작에 대한
연속성을 Client 에게 표현(노출)하는 것을 의미합니다.
이러한 HATEOAS 의 특징을 짧게 상태 전이 라고도 표현합니다.

아무튼!
JSON Response 으로도 HATEOAS 를 구현할 수는 있지만 약간 공정이 많이 들어갑니다.
관련된 Document 를 만들거나, 명세서를 만들어서 등록하거나... 등등 할 게 정말 많습니다.

반면에 HTML Response 는 그 자체만으로도 HATEOAS 를 구현할 수 있습니다.


예를 들어보죠.
아래와 같은 자신의 계좌 정보를 조회하는 HTTP 요청을 보냈다고 가정해보죠.

GET /accounts/12345 HTTP/1.1
Host: bank.example.com

그리고 이후에 응답으로 아래와 같이 JSON 을 받았다고 가정해보겠습니다.

{
  "userId": 12345,
  "balance": "100.00",
  "unit": "USD"
}

여러분, 이것만 보고 다음 동작으로 뭘할 수 있는지 알 수 있나요?
애초에 예측이 안됩니다. 최소한 예측이라도 하려면 link 라도 제공해줘야 하는데,
개발자들이 귀찮아서 안 한 모양입니다 😥😥😥


그렇다면 HTML 을 반환받았을 때는 어떨까요?

<html>
  <body>
    <div>Account number: 12345</div>
    <div>Balance: $100.00 USD</div>
    <div>Links:
        <a href="/accounts/12345/deposits">deposits</a>
        <a href="/accounts/12345/withdrawals">withdrawals</a>
        <a href="/accounts/12345/transfers">transfers</a>
        <a href="/accounts/12345/close-requests">close-requests</a>
    </div>
  <body>
</html>

어떤가요? a 태그를 통해서 저희는 어떤 동작을 할 수 있는지 알 수 있고,
href 에 제공되는 link 를 통해서 서버와도 추가적인 통신이 가능함을 알 수 있습니다.

이게 바로 HATEOAS 이며, 이게 바로 HTML 이 HATEOAS 에 강한 이유입니다.
그리고 HTMX 는 이런 REST 스타일을 지키기 위해서
HTML 을 반환하는 것이고요.

이외에도 HTML 을 반환은 여러 관점에서 나온 결론입니다.
이와 관련해서는 HTMX 창시자의 인터뷰 영상을 한번 쭉 보는 것을 추천합니다.
(제가 다 정리하려니까 좀 힘들더라구요 😅😅)



길고 장황한 답변

저 스스로가 납득하기 위해서 정리한 글입니다.
영상을 봤거나, 짧은 답변만으로 만족하셨다면 굳이 안 읽어보셔도 됩니다.


여러분의 API 는 정말 RESTful 한가요?

지금까지 HTMX 에 대해서 어느정도 설명을 했습니다.
그런데 여기까지 읽었어도 api 가 html 을 반환해야 되는 것이 약간
께름칙하신 분들이 계실 겁니다.

이러는 이유는 여러분들이 여태 강의나, 유튜브에서 따라치거나,
회사의 코드에서 봤던 REST API 가 거의 아래와 같은 형태로 설계되었기 때문입니다.

GET /users       [사용자 정보 목록조회]
GET /users/{id}  [사용자 정보 상세조회]
POST /users      [사용자 정보 등록]
PUT /users	     [사용자 정보 수정]
DELETE /users    [사용자 정보 삭제]

여기까지는 여러분들도 많이 보던 Rest API 의 endpoint 설계 방식일 겁니다.
위의 설계 방식을 통해 요청(request)에 한정해서 REST 방식을 지켰습니다.

하지만 Server 로부터 받는 반환값, 즉 응답(response) 대한 REST 제약 은 어떠신가요?
혹시 데이터를 JSON 형태로 단순히 변환하여 있는 그대로 Client 에 반환했나요?

그렇다면 여러분들은 REST API 구현에 실패하신 겁니다.
여러분들이 구현한 것은 HTTP API 입니다.


실패의 이유는 다음과 같습니다.

  1. 반환받은 값(JSON)이 self-descriptive 하지 않습니다.
  2. 반환받은 값(JSON)이 HATEOAS 를 지키지 않습니다.

self-descriptiveHATEOAS 는 REST 아키텍처를 만들기 위한
스타일(제약)중에서도 uniform interface 하위에 있는 4가지 조건 중 2가지 입니다.

잘 기억이 안나시나요? 기억을 되살리기 위해서 아래 REST 스타일을
위한 것들이 뭐가 있는지 다시 한번 확인합시다.



다시 보는 REST Style - uniform interface

위에서 본 API 기준으로 지켜준 것이면 👍, 아니면 👎 을 부여해봤습니다.

  • uniform interface
    • identification of resource : url 사용 👍
    • manipulation of resources through representations : HTTP Method 사용 👍
    • self-descriptive messages : 👎
    • hypermedia as the engine of application state (HATEOAS): 👎

참고: uniform interface 이 필요한 이유? 독립적인 진화!

  • 서버와 클라이언트가 각각 독립적으로 진화
  • 서버(또는 클라이언트)이 서로 독립적으로 변경되어도 서로 영향을 주지 않는다는 의미입니다.

그런데 대체 self-descriptiveHATEOAS 가 뭘까요?



👏 self-descriptive ?

이건 서버의 응답, 즉 메세지 자체만으로 사람에 의해서 해석이 가능한지를 의미합니다.

다만 여기서 말하는 해석이 가능하다 의 범주는 단순히 응답 자체에 자원에 대한 설명을
주절주절 쓰는 방식도 뿐만아니라, 응답에 대한 해설을 위한 명세서 가 있다면
이 또한 OK 입니다.

예를들어서 여러분들이 응답으로 content-type : text/html 을 받았으면,
그와 관련된 명세서를 찾아가서 보면 "해석이 가능"하게 되는 것이죠.


👏 HATEOAS ?

애플리케이션의 상태는 Hyperlink 를 이용해 전이되어야 한다는 겁니다.
짧게 얘기하자면 상태 전이 가 가능해야 된다는 겁니다.

여기서 말하는 상태 전이
사용자가 어떤 응답을 받고 나서 다음으로 서버에게 취할 수 있는 동작 의마합니다.

예를 들어서 여러분들이 Q&A 상세조회 를 하면
해당 응답으로 받은 HTML 에는 다음으로 취할 수 있는 행위들이 다음과 같습니다.

  • Q&A 목록조회 (GET /qna)
  • Q&A 이전/다음 글 조회 (GET /qna/{id})

여기서 중요한 것은 상태 전이가 link 를 통해서 가능하다는 점입니다.




JSON 로는 불가능한가?

JSON 응답을 받았어도 여전히 RESTful 하게 API 를 설계할 수 있습니다.
이와 관련해서는 아래 영상의 34:05 ~ 40:30 구간을 봐주세요!



??? : JSON 쓰면 REST 아님!!!

그런데 말이죠... 사실 근본 of 근본으로 치면,
json 으로는 REST 를 구현하면 안됩니다.

왜냐하면, REST 를 창시한 분(Roy T.Fielding) 께서 그렇게 아래와 같은
게시물을 작성하신 적이 있거든요.

글에서 작성자의 빡침이 느껴집니다.
특히 마지막에 Is there some broken manual somewhere that needs to be fixed?
라고 말하는 걸 보면 어느정도 짐작이 가죠.

하지만 요즘은 그냥 쌩까고(?) Rest API 라고 합니다.
내가 Rest API 라고 말하고 다니면 너가 뭘할 수 있는데?! 라는 느낌으로 말이죠 ㅎㅎ



튜닝의 끝은 순정, HTML

자, 여기까지 읽으면서 느꼈겠지만 우리가 흔히 아는 JSON 을 반환하는 API 는
REST 제약을 지킬 수는 있지만 구현하기가 난해하고 어려우며,
심지어 REST 의 아버지인 Roy T.Fielding 마저 손절(?)하는 겁니다.

이쯤에서 한번 생각을 해봅시다.
여러분 그냥 HTML 을 반환하면 어떨까요?

HTML 은 그자체만으로 self-descriptiveHATEOAS 를 모두 지킵니다.
일단 self-descriptive 의 경우 html 명세서 가 이미 있으니
REST 제약에 충족됩니다.

HATEOAS 는 어떨까요?
아주 간단한 예로 자신의 계좌정보를 조회하는 api 의 응답이 html 일 때를 봅시다.


HTML Resposne

<html>
    <body>
        <div>Account number: 12345</div>
        <div>Balance: $100.00 USD</div>
        <div>Links:
            <a href="/accounts/12345/deposits">deposits</a>
            <a href="/accounts/12345/withdrawals">withdrawals</a>
            <a href="/accounts/12345/transfers">transfers</a>
            <a href="/accounts/12345/close-requests">close-requests</a>
        </div>
    <body>
</html>
  • 다음 상태로 전이할 수 있는 여러 링크가 제공됩니다!
  • HATEOUS 를 충실히 지켰습니다.

어떤가요? 여태까지 몰랐지만 사실 REST 구현에 있어서
html 이 굉장히 적절한 미디어 타입이라는 것이 느껴지지 않나요?

HTMX 는 이러한 REST 의 규칙을 준수하기 위해서
api response 가 html 로 되도록 한 겁니다.





알아두면 좋은 링크들

문서: Hypermedia System

사실 HTMX 가 나오게 된 계기, 필요성에 대한 설명은 범위가 넓습니다.
제가 위에 설명한 건 어찌보면 새발의 피일지도 모르겠습니다.
HTMX 가 이루고자 하는 모든 것들은 결국 Hypermedia System 의 구축이기 때문이죠.
이와 관련해서는 무료로 읽을 수 있는 document 가 제공됩니다.
시간이 넉넉하면 한번 읽어보시길 바랍니다.

참고: https://hypermedia.systems/book/contents/


유튜브: Creator of HTMX Talks HTMX



profile
백엔드 개발자로 일하고 있는 식빵(🍞)입니다.

0개의 댓글