Go の Gin の基本とルーティング

Gin は Go で最も人気のある Web フレームワークの1つだ。高速で軽量、そして直感的な API を提供している。

Gin のインストール

go get -u github.com/gin-gonic/gin

最小限のサーバー

package main

import "github.com/gin-gonic/gin"

func main() {
    r := gin.Default()
    
    r.GET("/", func(c *gin.Context) {
        c.JSON(200, gin.H{
            "message": "Hello, World!",
        })
    })
    
    r.Run(":8080")
}

gin.Default() はロガーとリカバリーミドルウェアが設定済みのエンジンを返す。r.Run() でサーバーが起動し、デフォルトでは 8080 番ポートでリッスンする。

HTTP メソッドとルーティング

Gin は各 HTTP メソッドに対応したメソッドを提供している。

r.GET("/users", getUsers)
r.POST("/users", createUser)
r.PUT("/users/:id", updateUser)
r.DELETE("/users/:id", deleteUser)
r.PATCH("/users/:id", patchUser)

パスパラメータ

URL 内の動的な部分は :パラメータ名 で定義する。

r.GET("/users/:id", func(c *gin.Context) {
    id := c.Param("id")
    c.JSON(200, gin.H{"user_id": id})
})

r.GET("/posts/:year/:month", func(c *gin.Context) {
    year := c.Param("year")
    month := c.Param("month")
    c.JSON(200, gin.H{"year": year, "month": month})
})

* を使うとワイルドカードになり、残りのパス全体をキャプチャする。

r.GET("/files/*filepath", func(c *gin.Context) {
    filepath := c.Param("filepath")
    // /files/images/logo.png → filepath = "/images/logo.png"
    c.String(200, "File: %s", filepath)
})

クエリパラメータ

クエリ文字列は Query メソッドで取得する。

// GET /search?q=golang&page=1
r.GET("/search", func(c *gin.Context) {
    query := c.Query("q")
    page := c.DefaultQuery("page", "1")
    
    c.JSON(200, gin.H{
        "query": query,
        "page":  page,
    })
})

DefaultQuery はパラメータがない場合のデフォルト値を指定できる。

ルートグループ

共通のプレフィックスを持つルートはグループ化できる。

api := r.Group("/api")
{
    v1 := api.Group("/v1")
    {
        v1.GET("/users", getUsers)
        v1.POST("/users", createUser)
    }
    
    v2 := api.Group("/v2")
    {
        v2.GET("/users", getUsersV2)
    }
}

これで /api/v1/users/api/v2/users のようなルートが定義される。グループにはミドルウェアを適用することもでき、認証が必要なルートをまとめるときに便利だ。

gin.H について

gin.H は map[string]interface{} のエイリアスだ。JSON レスポンスを簡潔に書ける。

// この2つは同じ
c.JSON(200, gin.H{"name": "Alice", "age": 30})
c.JSON(200, map[string]interface{}{"name": "Alice", "age": 30})

構造体を返すこともできる。

type User struct {
    Name string `json:"name"`
    Age  int    `json:"age"`
}

r.GET("/user", func(c *gin.Context) {
    user := User{Name: "Alice", Age: 30}
    c.JSON(200, user)
})

Gin のルーティングは httprouter をベースにしており、非常に高速だ。シンプルな API から複雑なルート構成まで、柔軟に対応できる。