ほぼ自分用の忘備録です。
背景
Go+Gin構成のwebアプリでは、ファイルとして用意したテンプレートをHTTPレスポンスで返すのは簡単です。以下のようなスニペットになります。
func main() {
router := gin.Default()
router.LoadHTMLFiles("HTMLテンプレートファイルのパス")
router.GET("リクエストエンドポイントのuri", handler)
}
func handler(ginctx *gin.Context) {
ginctx.HTML(http.StatusOK, "HTMLテンプレートファイル", gin.H{
キー: バリュー
})
}
課題
HTMLテンプレートをGoogle Cloud Storage(以下GCSと略)に置いておき、そこから読み込んで返したい場合、直接GCSから取得してくれる関数はGinにはありません。
解決
以下のスニペットで可能になりました。エラー処理のコードは省略しています。これでいいのかちょっと不安な箇所もありますが、とりあえず期待動作はしています。
func main() {
router := gin.Default()
router.GET("リクエストエンドポイントのuri", handler)
}
func handler(ginctx *gin.Context) {
// GCSからHTMLテンプレートをロード
ctx := context.Background()
storageclient, _ := storage.NewClient(ctx)
reader, _ := storageclient.Bucket("バケット名")
.Object("HTMLテンプレートのオブジェクト名").NewReader(ctx)
content_bin, _ := io.ReadAll(reader)
reader.Close()
// GCSから読み出した結果はバイナリなので文字列に変換
content_str, _ := *(*string)(unsafe.Pointer(&content_bin)
// テンプレートとして登録
router := gin.Default()
template, _ := template.New("").Delims("{{", "}}").Funcs(router.FuncMap).Parse(content_str)
router.SetHTMLTemplate(template)
// レスポンスで返す
html := router.HTMLRender.Instance("", gin.H{
キー: バリュー
})
ginctx.Render(http.StatusOK, html)
}
バイナリ→文字列の変換には「忘れがちなGoでbyteをstringに変換する方法をベンチマークしてみた。」を参考にしました。