アプリケーションを、その言語に用意されている機能(標準パッケージ)だけで作ることは大変なことです。そこで、アプリケーションの作成を助けるフレームワーク(framework)というものを使います。Web アプリケーションのためのフレームワークは、WAF(Web Application Framework)と言います。
Go の WAF は、まだ黎明期にあるらしく、デファクトスタンダード(de facto standard、業界標準)が決まっていない状態です。現在、Go の WAF で有名なところは、次のようなものです。
シンプルなもの(ルーティングのみ) | フルスタックなもの(セッションなど) | gin gogi |
revel mux |
デファクトスタンダードが決まるまでは、シンプルな WAF を使い、デファクトスタンダードが決まってからフルスタックな WAF を採用するのが良いという意見があります。また、私自身もシンプルなものが好きなので、ここでは gin を学習していきたいと思います。
Gin の環境設定は簡単です。ターミナルに次のように入力してエンターキーを押すだけです。macOS、Mint(Ubuntu)、CentOS 7で同じコードです。少し時間がかかる場合があります。
go get github.com/gin-gonic/gin
Gin では、静的なページと動的なページとで区別はありませんが、一応静的なページとして、サンプルコードを掲載します。
次のようなディレクトリ構成にします。
gin/
- main.go
- templates/
- - index.html
- styles/
- - style.css
ディレクトリ構成、ディレクトリ名、ファイル名は自由に決めて大丈夫です。
package main
import (
// Go の標準パッケージではなく、gin のパッケージをインポートします
"github.com/gin-gonic/gin"
)
func main() {
// gin の変数を定義しています
router := gin.Default()
// css などの静的ファイルのディレクトリを指定しています
router.Static("styles", "./styles")
// HTML ファイルのディレクトリを指定しています
router.LoadHTMLGlob("templates/*.html")
// "/"ルートと handler 関数を関連づけています。handler という関数名は任意で付けた関数名です
router.GET("/", handler)
// サーバーを起動しています
router.Run()
}
// 引数の型はデフォルトだと思います、引数名は任意でしょう
func handler(ctx *gin.Context) {
// 200 の意味はわかりません。デフォルトではないかと思います
// gin.H{}で、go ファイルの変数を HTML テンプレートに渡します。この例では何も渡していません。
ctx.HTML(200, "index.html", gin.H{})
}
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>Gin / 静的なページ</title>
<link rel="stylesheet" href="../styles/style.css">
</head>
<body>
<h1>Go Gin</h1>
<div align="center">
<p>静的なページ</p>
</div>
</body>
</html>
body {
color: gray;
}
h1 {
text-align: center;
font-family: sans-serif;
font-weight: 100;
margin-top: 60px;
}
実行する場合は、ターミナルで gin ディレクトリに移動して、go run main.go と入力して、エンターキーを押します。
go run main.go
[GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached.
[GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.
- using env: export GIN_MODE=release
- using code: gin.SetMode(gin.ReleaseMode)
[GIN-debug] GET /styles/*filepath --> github.com/gin-gonic/gin.(*RouterGroup).createStaticHandler.func1 (3 handlers)
[GIN-debug] HEAD /styles/*filepath --> github.com/gin-gonic/gin.(*RouterGroup).createStaticHandler.func1 (3 handlers)
[GIN-debug] Loaded HTML Templates (2):
-
- index.html
[GIN-debug] GET / --> main.handler (3 handlers)
[GIN-debug] Environment variable PORT is undefined. Using port :8080 by default
[GIN-debug] Listening and serving HTTP on :8080
Gin の場合は、多くのコードが表示されます。
macOS の場合は、次のようなアラートが表示される場合があります。「許可」をクリックしてください。
ブラウザで localhost:8080/ にアクセスすると次のように表示されます。Gin では、ポートは、自動的に、8080 なるみたいです。
さきほども言いましたが、Gin には静的、動的の区別はないみたいです。動的な動作は、Go ファイルから HTML テンプレートへ変数(値)を実際に渡すことで実現します。
ディレクトリ構成と style.css は先ほど同じです。
package main
import (
"github.com/gin-gonic/gin"
"time" // 時刻を取得するために time パッケージも読み込みます
)
func main() {
router := gin.Default()
// css などの静的ファイルのディレクトリを指定
router.Static("styles", "./styles")
router.LoadHTMLGlob("templates/*.html")
router.GET("/", handler)
router.Run()
}
func handler(ctx *gin.Context) {
now := time.Now()
// gin.H に、map 形式で値を渡します
ctx.HTML(200, "index.html", gin.H{"hour":now.Hour(), "minute":now.Minute()})
}
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>Gin / 動的なページ</title>
<link rel="stylesheet" href="../styles/style.css">
</head>
<body>
<h1>Go Gin</h1>
<div align="center">
// Go ファイルで指定した変数(値)を {{.キー名}} の形で呼び出します
<p>あなたが、このページにアクセスした時刻は、{{.hour}}時{{.minute}}分です。</p>
</div>
</body>
</html>