My Note

自己理解のためのブログ

GoのWebフレームワーク Echoでの開発記録(DBのデータをmapにしてTemplate Rendering でページに表示する)

はじめに

以前の記事で初めて Echoで Template Renderingを利用してページを作成しました。 今回はEchoで個人開発をしていてそのTemplate Renderingを利用した備忘録です。

yhidetoshi.hatenablog.com

アプリのディレクトリ構成

MVCモデルを意識した構成にしています。

  • api/
  • model/
    • モデル部分を実装
  • view/
    • ビュー部分を実装
  • handler/
    • コントローラー部分を実装
  • conf/

ディレクトリ構成

❯ tree -L 3
.
├── README.md
├── TEST_Client
│   └── cors
│       ├── index.php
│       └── script.js
├── api
│   ├── base.go
│   ├── client.go
│   ├── crypto_batch.go
│   ├── crypto_coincheck.go
│   ├── crypto_coincheck_test.go
│   ├── crypto_gmo.go
│   ├── crypto_gmo_test.go
│   ├── healthcheck.go
│   ├── healthcheck_test.go
│   ├── investment_trust.go
│   └── metal.go
├── conf
│   └── config.go
├── docker
│   ├── mysql
│   │   ├── Dockerfile
│   │   ├── data
│   │   └── my.cnf
│   └── redis
│       └── data
├── docker-compose.yml
├── go.mod
├── go.sum
├── handler
│   ├── auth.go
│   ├── crypto.go
│   └── top.go
├── main.go
├── model
│   ├── crypto.go
│   ├── db.go
│   ├── stock.go
│   └── user.go
├── public
│   └── assets
│       └── css
├── staticcheck.conf
└── view
    ├── input_crypto.html
    ├── login.html
    ├── mypage.html
    ├── signup.html
    └── top.html

やること

tokens テーブルにあるトークン一覧をDBから取得してhtmlの画面にプルダウンで表示させます。 これは、トークンは増えていく場合もあるためtokenが追加されたら動的にプルダウンメニューに追加されるようにするためです。

  • 表示する画面

  • tokens テーブル
mysql> select id,token from tokens;
+----+-------+
| id | token |
+----+-------+
|  1 | BTC   |
|  2 | ETH   |
+----+-------+
  • handler/crypto_buy_save.go から抜粋
func ShowCryptoTradeDataHTML(c echo.Context) error {
    tokens := model.GetTokenIDs()
    return c.Render(http.StatusOK, "crypto_trade", tokens)
}
  • model/crypto.go から抜粋
    • ORMのgormを利用して、構造体の Tokenにデータを渡して map ( map[int]string{} )にする
type Token struct {
    ID        int       `json:"id" gorm:"primaryKey"`
    Token     string    `json:"token"`
    CreatedAt time.Time `gorm:"autoCreateTime"`
    UpdatedAt time.Time `gorn:"autoUpdateTime"`
}

func GetTokenIDs() map[int]string {
    var token []Token
    tokenResults := map[int]string{}

    db.Table("tokens").Select("id", "token").Order("id asc").
        Find(&token)
    for _, value := range token {
        tokenResults[value.ID] = value.Token
    }
    return tokenResults
}
  • view/input_crypto.html から抜粋
    • mapのデータを表示する
      • {{ range $key, $value := . }} このように定義した場合は、mapの keyを 変数名: $key に。 value を 変数名$value になる
<div class="mb-3">
  <select name="token" required>
    <option value="" selected disabled>ティッカーを選択する</option>
    {{ range $key, $value := . }}
    <option value={{ $key }}>{{ $value }}</option>
    {{ end }}
  </select>
</div>
  • main.go から抜粋
type TemplateRender struct {
    templates *template.Template
}

func (t *TemplateRender) Render(w io.Writer, name string, data interface{}, c echo.Context) error {
    return t.templates.ExecuteTemplate(w, name, data)
}
    renderer := &TemplateRender{
        templates: template.Must(template.ParseGlob("view/*.html")),
    }
    e.Renderer = renderer
    e.GET("/crypto_trade", handler.ShowCryptoTradeDataHTML)

    // Staticファイル
    e.Static("/assets", "public/assets")