Gin + HTMX로 Counter 만들기

본 글은 Claude 4 Sonnet으로 작성 후 수정한 글입니다.

웹 개발에서 빠른 프로토타이핑과 간단한 상호작용이 필요할 때 Gin 프레임워크와 HTMX의 조합은 매우 효과적이다. 이 글에서는 Go의 Gin 프레임워크 기본 사용법과 HTMX를 활용한 실시간 Counter 예제를 살펴본다.


Gin 프레임워크 소개

Gin은 Go 언어로 작성된 경량 웹 프레임워크다. Express.js에서 영감을 받아 만들어졌으며, 빠른 성능과 간단한 API를 제공한다.

주요 특징

  • 빠른 HTTP 라우터
  • 미들웨어 지원
  • JSON 유효성 검사
  • 에러 관리
  • HTTP/2 지원

프로젝트 구조

go-counter/
├── main.go
├── handlers/
│   └── counter.go
└── templates/
    └── counter.html

메인 서버 설정

// main.go
package main

import (
	"go-api/handlers"
	"github.com/gin-gonic/gin"
)

func main() {
	// 릴리즈 모드 설정 (운영 환경에서 사용)
	// gin.SetMode(gin.ReleaseMode)
	
	// Gin 라우터 생성
	r := gin.Default()
	
	// HTML Templates 설정
	r.LoadHTMLGlob("templates/*")
	
	// CORS 미들웨어 적용 (필요시)
	r.Use(func(c *gin.Context) {
		c.Writer.Header().Set("Access-Control-Allow-Origin", "*")
		c.Writer.Header().Set("Access-Control-Allow-Methods", "GET, POST")
		c.Writer.Header().Set("Access-Control-Allow-Headers", "Content-Type")
		c.Next()
	})
	
	// 라우트 그룹 설정
	counter := r.Group("/counter")
	{
		counter.GET("/", handlers.ShowCounter)        // Counter 페이지 표시
		counter.POST("/increment", handlers.Increment) // Counter 증가
	}
	
	// 서버 시작
	r.Run(":8080")
}

핵심 개념 설명

  • gin.Default(): 기본 미들웨어(Logger, Recovery)가 포함된 Gin 엔진 생성
  • LoadHTMLGlob(): HTML 템플릿 파일들을 로드
  • r.Group(): 라우트를 그룹화하여 관리
  • CORS 미들웨어: 브라우저의 Same-Origin Policy 제한 해제

핸들러 함수 구현

// handlers/counter.go
package handlers

import (
	"net/http"
	"strconv"
	"github.com/gin-gonic/gin"
)

// 전역 카운터 변수
var counter = 0

// Counter 페이지를 표시하는 핸들러
func ShowCounter(c *gin.Context) {
	c.HTML(http.StatusOK, "counter.html", gin.H{
		"counter": counter,
	})
}

// Counter 값을 증가시키는 핸들러
func Increment(c *gin.Context) {
	counter++
	// HTMX는 HTML 응답을 기대하므로 숫자만 반환
	c.String(http.StatusOK, strconv.Itoa(counter))
}

Gin Context 활용법

  • c.HTML(): HTML 템플릿을 렌더링하여 응답
  • c.String(): 문자열 응답 전송
  • gin.H{}: 템플릿에 전달할 데이터를 정의하는 맵

HTMX를 활용한 프론트엔드

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <script src="https://unpkg.com/htmx.org@1.9.10"></script>
</head>
<body>
<h1>Counter Example</h1>

<div>
    <!-- counter 변수 -->
    <span id="counter">{{.counter}}</span>
</div>

<!-- 버튼 클릭 시 서버에 POST 요청 보내고, 결과를 counter 영역에 교체 -->
<button hx-post="/counter/increment" hx-target="#counter" hx-swap="innerHTML">
    Increment
</button>
</body>
</html>

실행 방법

$ go mod init go-counter
$ go get github.com/gin-gonic/gin
$ go run main.go

브라우저에서 http://localhost:8080/counter 접속


이 예제는 Gin과 HTMX의 기본적인 조합을 보여준다. 두 기술의 단순함과 효율성을 활용하면 복잡한 SPA 프레임워크 없이도 상호작용이 풍부한 웹 애플리케이션을 빠르게 개발할 수 있다.