2023/05/07

GCSからHTMLテンプレートを読み込んでHTTPレスポンスで返す [Go]

 ほぼ自分用の忘備録です。


背景

 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に変換する方法をベンチマークしてみた。」を参考にしました。

2023/04/12

Cassandraって何者?

現在参画しているプロジェクトで、はじめてApache Cassandraを使っています。Cassandraはオープンソースのデータベースで、クラウド上に実装して使う例も多数あります。今回参画しているプロジェクトもそうです。

本記事では、これを分類してみましょう。


Let's 分類


分散型

複数のインフラに分散実装し、全体として1つのデータベースとして機能する分散型データベースであるのが、たぶん最大の特徴です。この点はシステム屋さんには重要でも、純粋にコードを書くだけのソフト屋さんにとっては意識することはありません。

リレーショナル or ドキュメント指向 or キーバリュー型

リレーショナルデータベースと同様にあらかじめスキーマの定義が必要なスキーマ・オン・ライトですが、JOINはありません。あらかじめスキーマの定義が必要ということは半構造化データを前提としているわけではないので(JSON型が使えるのは別の話)、ドキュメント指向でもキーバリュー型でもありません。
Cassandraは、どれでもないですね。
(20230/04/17修正 : キーバリュー型に分類されるそうです。しかしキーバリュー型の代表とも言えるredisとも似てない。)

SQL or NoSQL

Cassandraでのデータ操作はSQLではなく、SQLに似たCQLで行います。SQL互換ではないのでNoSQLに分類されるようです。しかしNoSQLというと「SQLライクな言語」さえもなくてAPIで操作するものも珍しくない(Firestoreとか)と思うので、NoSQLに分類するのも違うと感じます。
Cassandraは、どちらに分類してもしっくりきません。

まとめ?

他に似ていない独自ですね。「俺か、俺以外か」という分類の仕方がいいかもしれません。

2023/01/31

オンプレミスへの回帰について

前回の記事「クラウドへの移行について」と真逆のタイトルです。


ここ3年ほどで何度か『クラウド移行したけど運用コストが予想より高かったのでオンプレに回帰した』という趣旨の記事をネット上で見かけることがありました。しかしそれらの記事にはどれも、具体的にどんな問題があったかについて記述されていません。具体的でないので、記事そのものが疑わしいと感じていました。

クラウドへの移行について」の最後に紹介した「NTTぷらら、映像配信のストレージをAzureからオンプレミスに移行、ストレージ利用コストを削減」のような一部だけ回帰のケースは時々見ます。これらの記事には具体的な記述があり著者も明確なので、事実であろうことを疑う必要もないでしょう。クラウドだっていつでもどんな状況でも優れているわけではない事例です。


最初に記したような完全回帰の記事にはなぜ具体的な記述がないのかですが、こういった記事は、世の中のクラウドへの移行について行けないあるいはクラウド移行したくない事情を持っている一部の人達のプロパガンダだと予想しています。だから具体的な記述がないのではないでしょうか。


また、前回の記事「クラウドへの移行について」にも記したように、マイグレーションしただけではランニングコストが高くつきます。最低限のマイグレーションだけしてクラウドへの移行が終わったと勘違いしてそのまま使い続けて、「高い」と間違った評価をしている可能性も高いと思います。

ランニングコストも低く抑えたいなら、クラウドに特化するモダナイゼーションも必須です。これはコンテナ技術を使ってスケーリングに対応することとは異なります。