1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Gin フレームワークの基礎

Posted at

Gin は Go 言語で実装された軸量込みで高性能な Web フレームワークです。RESTful API サーバーや Web アプリの開発に適しています。ここでは Gin の基本的な使い方を紹介します。

Gin の特徴

高性能
スレッドレスな HTTP リクエストを高速に処理します。

シンプルな API
ルーティングやミドルウェアが直感的で、視覚的に使いやすい。

ミドルウェア支援
ログ出力や認証などをカスタマイズした処理の結合が可能です。

コミュニティサポート
コミュニティが浸透しているため、問題が発生した時に情報を容易に採得できます。

インストール

下記コマンドを実行して Gin をインストールします。

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

go.mod にバージョン情報が追加されます

require github.com/gin-gonic/gin v1.9.0

Gin の基本的な使い方

1. 最小構成のサーバ

これは Gin の最小構成の Web サーバーのコードです。

package main

import (
    "net/http"

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

func main() {
    // デフォルトのエンジンを作成
    router := gin.Default()

    // ルート設定
    router.GET("/", func(c *gin.Context) {
        c.String(http.StatusOK, "Hello, Gin!")
    })

    // 3000番ポートでサーバ起動
    router.Run(":3000")
}

コード実行後、http://localhost:3000/ にアクセスすると「Hello, Gin!」が表示されます。

2. ルーティング

HTTP メソッドに対応したルートを設定します。

router.GET("/ping", func(c *gin.Context) {
    c.String(http.StatusOK, "pong")
})

パスパラメータとクエリパラメータ

ルートのパラメータを簡単に取得できます。

// パスパラメータ
router.GET("/user/:id", func(c *gin.Context) {
    id := c.Param("id")
    c.String(http.StatusOK, "User ID: %s", id)
})

// クエリパラメータ
router.GET("/search", func(c *gin.Context) {
    query := c.Query("q")
    c.String(http.StatusOK, "Search query: %s", query)
})

3. JSON レスポンス

JSON 形式のレスポンスを返す例です。

router.GET("/json", func(c *gin.Context) {
    data := gin.H{
        "message": "hello",
        "status":  200,
    }
    c.JSON(http.StatusOK, data)
})

gin.H は map[string]interface{} のシンタックスシュガーです。

ミドルウェア

1. 組み込みミドルウェア

Logger: ログ出力

Recovery: パニックが発生した際のエラー対処

2. カスタムミドルウェア

自分で定義するミドルウェアの例です。

func MyMiddleware() gin.HandlerFunc {
    return func(c *gin.Context) {
        // 前処理
        c.Next()
        // 後処理
    }
}

func main() {
    r := gin.Default()
    r.Use(MyMiddleware())

    r.GET("/", func(c *gin.Context) {
        c.String(http.StatusOK, "Hello, Middleware!")
    })

    r.Run(":3000")
}

グループルーティング

グループを使用すると、ルートを結合し、共通のパスやミドルウェアを適用できます。

func main() {
    r := gin.Default()

    api := r.Group("/api")
    {
        api.GET("/users", func(c *gin.Context) {
            c.String(http.StatusOK, "GET /api/users")
        })
        api.POST("/users", func(c *gin.Context) {
            c.String(http.StatusOK, "POST /api/users")
        })
    }

    admin := r.Group("/admin", AuthMiddleware())
    {
        admin.GET("/dashboard", func(c *gin.Context) {
            c.String(http.StatusOK, "Admin Dashboard")
        })
    }

    r.Run(":3000")
}

テンプレートエンジン

HTML テンプレートをレンダリングする例です。

func main() {
    r := gin.Default()
    r.LoadHTMLGlob("templates/*")

    r.GET("/", func(c *gin.Context) {
        c.HTML(http.StatusOK, "index.html", gin.H{
            "title":   "Main Page",
            "message": "Hello, Gin Template!",
        })
    })

    r.Run(":3000")
}

templates/index.html の例:

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>{{ .title }}</title>
</head>
<body>
    <p>{{ .message }}</p>
</body>
</html>

CRUD 実装

シンプルな CRUD 操作を Gin で実装する例を紹介します。

モデル

type User struct {
    ID    int    `json:"id"`
    Name  string `json:"name"`
    Email string `json:"email"`
}

var users = []User{
    {ID: 1, Name: "Alice", Email: "alice@example.com"},
    {ID: 2, Name: "Bob", Email: "bob@example.com"},
}

エンドポイント

Create (追加)

router.POST("/users", func(c *gin.Context) {
    var newUser User
    if err := c.ShouldBindJSON(&newUser); err != nil {
        c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
        return
    }
    newUser.ID = len(users) + 1
    users = append(users, newUser)
    c.JSON(http.StatusCreated, newUser)
})

Read (読み取り)

router.GET("/users", func(c *gin.Context) {
    c.JSON(http.StatusOK, users)
})

router.GET("/users/:id", func(c *gin.Context) {
    id := c.Param("id")
    for _, user := range users {
        if strconv.Itoa(user.ID) == id {
            c.JSON(http.StatusOK, user)
            return
        }
    }
    c.JSON(http.StatusNotFound, gin.H{"error": "User not found"})
})

Update (更新)

router.PUT("/users/:id", func(c *gin.Context) {
    id := c.Param("id")
    var updatedUser User
    if err := c.ShouldBindJSON(&updatedUser); err != nil {
        c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
        return
    }
    for i, user := range users {
        if strconv.Itoa(user.ID) == id {
            users[i] = updatedUser
            users[i].ID = user.ID
            c.JSON(http.StatusOK, users[i])
            return
        }
    }
    c.JSON(http.StatusNotFound, gin.H{"error": "User not found"})
})

Delete (削除)

router.DELETE("/users/:id", func(c *gin.Context) {
    id := c.Param("id")
    for i, user := range users {
        if strconv.Itoa(user.ID) == id {
            users = append(users[:i], users[i+1:]...)
            c.JSON(http.StatusOK, gin.H{"message": "User deleted"})
            return
        }
    }
    c.JSON(http.StatusNotFound, gin.H{"error": "User not found"})
})
1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?