## 손쉽게 서버와의 강력한 비동기 통신 구현 {#sec-b77e387924b4}
[[HTMX]]는 Django와 같은 서버 중심의 웹 개발 프레임워크에서 [[JavaScript]]의 복잡성 없이도 강력한 비동기 기능을 구현할 수 있게 해줍니다. 이번 편에서는 **HTMX가 Ajax 요청을 처리하는 내부 원리**와 **실제 Django 뷰와의 통신 방식**을 구체적인 예제를 통해 알아보겠습니다.

## [[HTMX]]의 핵심: HTML이 곧 메시지입니다 {#sec-fcb60a4b40b4}
기본적인 Ajax 통신(예: axios, fetch)은 서버로부터 JSON 데이터를 받고, 이를 자바스크립트가 해석해서 화면을 다시 그리는 과정을 거칩니다. 하지만 HTMX는 **'Hypermedia as the Engine of Application State(HATEOAS)'** 원칙을 따릅니다. 즉, 서버가 데이터(JSON) 대신 **완성된 HTML 조각**을 보내고, HTMX는 이를 지정된 위치에 '교체'만 합니다.
**HTMX의 Ajax 통신 4단계**
1. **이벤트 발생:** 사용자가 HTML 요소(버튼 등)와 상호작용합니다.
2. **Ajax 요청:** HTMX가 브라우저의 `fetch` API를 호출하여 서버에 요청을 보냅니다.
3. **HTML 응답:** 서버는 로직을 처리한 후, 전체 페이지가 아닌 **필요한 부분의 HTML 조각**만 반환합니다.
4. **DOM 교체(Swap):** HTMX가 응답받은 HTML을 `hx-target`으로 지정된 요소에 즉시 삽입합니다.
## 실전 예제: "좋아요" 버튼 구현하기 {#sec-5eb5b07b3b51}
단순히 숫자를 바꾸는 것을 넘어, 서버와 어떻게 HTML 조각을 주고받는지 살펴보겠습니다.
### 1. CSRF 토큰의 준비 {#sec-7cb7dfe5c7ec}
Django는 보안을 위해 POST 요청 시 CSRF(Cross-Site Request Forgery) 토큰을 필수로 요구합니다. HTMX의 `hx-post` 역시 예외는 아닙니다. 이를 처리하는 두 가지 방법을 알아보겠습니다.
#### 방법 A: 개별 요소에 직접 설정하기 (기본형)
가장 직접적인 방법은 `hx-headers` 속성을 사용하여 요청 헤더에 토큰을 담아 보내는 것입니다.
```html
```
#### 방법 B: 전역 스크립트로 자동화하기 (권장)
매번 버튼마다 토큰 코드를 넣는 것은 번거롭습니다. `base.html`과 같은 공통 템플릿의 `
` 혹은 `` 하단에 아래 스크립트를 추가하면, 모든 HTMX 요청에 자동으로 CSRF 토큰이 포함됩니다.
```html
```
이렇게 설정해두면 이후 작성하는 모든 `hx-post` 코드에서 별도의 토큰 설정 없이도 Django의 보안 검사를 가뿐히 통과할 수 있습니다.
### 2. 프론트엔드 (Template) {#sec-cad7db10ba2b}
`hx-post`로 요청을 보내고, 서버가 주는 응답으로 `#like-section` 전체를 갈아 끼우는 방식입니다.
```html
```
이 예제처럼 `hx-target`과 `hx-swap`이 HTML 태그 안에 명시되어 있으면, 나중에 코드를 다시 읽을 때 "이 버튼을 누르면 어디가 어떻게 바뀌는지"를 자바스크립트 파일을 뒤지지 않고도 바로 알 수 있습니다.
개인적인 느낌으로는 코드를 보려면 백엔드의 View함수를 뒤져봐야 하는 것은 조금 불편할 수는 있지만, 위 예제처럼 html 태그안에 `hx-` 코드가 심어져 있으므로 인라인 JavaScript 보다는 **Locality of Behavior**측면에서 나은 것인가? 싶기도 합니다.
### 3. 백엔드 (Django View) {#sec-1fda4c57da3b}
여기서 중요한 점은 **`JsonResponse`가 아니라 `render`를 사용한다**는 것입니다.
```python
from django.shortcuts import render
def like_post(request):
# 좋아요 로직 처리 (예: DB 업데이트)
new_count = 10
# 전체 페이지가 아닌, 버튼 부분만 포함된 작은 템플릿 조각을 반환합니다.
return render(request, 'partials/_like_button.html', {
'likes_count': new_count
})
```
### 4. 응답용 부분 템플릿 {#sec-ce5390bdc052}
서버가 클라이언트에게 전달할 'HTML 조각'입니다. hx-swap="outerHTML" 설정을 했으므로, 기존의 #like-section 전체를 이 내용이 대체하게 됩니다.
```HTML
```
### 왜 이렇게 하나요? (원리의 이해) {#sec-67af112c65f1}
기존 방식에서는 `JsonResponse({'likes': 10})`를 받은 후, 자바스크립트에서 `document.getElementById('count').innerText = data.likes`와 같은 코드를 작성해야 했습니다.
하지만 [[HTMX]]방식은:
1. **로직의 파편화 방지:** "좋아요가 눌렸을 때 화면이 어떻게 변해야 하는가"에 대한 정의를 서버(Django 템플릿)가 관리합니다.
2. **데이터-뷰 동기화:** 서버에서 보낸 HTML이 그대로 화면에 박히기 때문에, 클라이언트 측에서 데이터를 가공할 때 발생하는 실수가 사라집니다.
## 이번 화를 마치며 {#sec-b28d1b5245c5}
[[HTMX]]를 사용한다는 것은 단순히 코드를 줄이는 것이 아니라, 웹의 본연의 기능인 'Hypermedia(HTML)'를 최대한 활용하는 방식으로 회귀하는 것입니다. 이를 통해 개발자는 자바스크립트 상태 관리의 지옥에서 벗어나 서버 로직에 더 집중할 수 있게 됩니다.
**관련글 읽기** :
- [Django와 HTMX로 동적 웹 개발을 단순화하기 (1편)](/ko/whitedec/2025/1/27/django-htmx-dynamic-web-simplification/)
- [Django와 HTMX로 동적 웹 개발 단순화하기 (3편): Django 통합 방법](/ko/whitedec/2025/1/27/django-htmx-dynamic-web-simplification-3/)
- [Django와 HTMX로 동적 웹 개발 단순화하기 (4편): Payload 전송 방식](/ko/whitedec/2025/1/27/django-htmx-csrf-token-integration/)
- [Django와 HTMX로 동적 웹 개발 단순화: Form과 Serializer 활용법](/ko/whitedec/2026/4/22/django-htmx-forms-serializer-usage/)
- [Django와 HTMX로 동적 웹 개발을 단순화하기: Trigger 활용법](/ko/whitedec/2026/4/23/django-htmx-dynamic-web-development-trigger/)