Goに愛を注ぐことが最近の楽しみな私です。
今回はGoのWAFであるGinを使ってTODOアプリを作ってみました。 あんまりGinの情報が無いので何かの参考になればなと。
「能書きはいいからコード見せろや!」って方はこちらのリポジトリを見て下さいまし。 github.com
Ginのお勉強
まずはGinってなんぞや?ってところから学びました。
かるーくGinのリポジトリにあるREADMEに目を通して、 そっから「プロジェクトをどういう形にすればいいんだ?」ってなったので、エウレカさんのテックブログの記事を参考にしました。
あとはGinやxormのドキュメントをチラチラと。
Documentation - xorm: Simple & Powerful ORM Framework for Go Programming Language
構成
構成はほぼエウレカさんの記事のままですね。
. ├── README.md ├── controllers │ └── task.go ├── main.go ├── models │ └── task.go └── views └── home.tmpl
説明
main.go
main.goでは
- 各routeの設定
- Controllerを使って取得した値をViewに渡す
ってなことをやってます。
package main import ( "gin-sandbox/controllers" "github.com/gin-gonic/gin" "net/http" ) func main() { router := gin.Default() // viewディレクトリを指定 router.LoadHTMLGlob("views/*") router.GET("/", func(c *gin.Context) { ctrl := task.NewTask() // ControllerのGetAllメソッドを使って全てのタスクを取得 tasks := ctrl.GetAll() c.HTML(http.StatusOK, "home.tmpl", gin.H{ "tasks": tasks, }) }) router.POST("/", func(c *gin.Context) { text := c.PostForm("text") ctrl := task.NewTask() // ControllerのCreateメソッドを使ってタスクを新規作成 ctrl.Create(text) tasks := ctrl.GetAll() c.HTML(http.StatusOK, "home.tmpl", gin.H{ "tasks": tasks, }) }) router.Run(":8080") }
controllers/task.go
controllers/task.goはTask構造体作ってそこに各メソッドを突っ込んでる感じですね。
main.goで使うためにNewTask()で作ったTask構造体を使えるようにしています。
各メソッドはmodelを通してDBアクセスした結果を返したりしてるだけです。
package task import ( "gin-sandbox/models" ) type Task struct { } func NewTask() Task { return Task{} } // 指定のタスクを取得(今回未使用) func (c Task) Get(n int) interface{} { repo := task.NewTaskRepository() task := repo.GetByID(n) return task } // 全てのタスクを取得 func (c Task) GetAll() interface{} { repo := task.NewTaskRepository() tasks := repo.GetAll() return tasks } // タスクを新規作成 func (c Task) Create(text string) { repo := task.NewTaskRepository() repo.Create(text) }
models/task.go
models/task.goではDBアクセスを主にやってます。
Repository構造体にDBアクセスを行うメソッドを詰め込んでるって感じですね。
package task import ( "github.com/go-xorm/xorm" _ "github.com/go-sql-driver/mysql" ) var engine *xorm.Engine func init() { var err error // DBの接続設定 engine, err = xorm.NewEngine("mysql", "root:@/gin-todo") if err != nil { panic(err) } } // DB上のtaskテーブルとマッピング type Task struct { ID int `json:"id" xorm:"'id'"` Text string `json:"text" xorm:"'text'"` } // GetAllの時に使用 type Tasks []Task type TaskRepository struct { } func NewTaskRepository() TaskRepository { return TaskRepository{} } func (m TaskRepository) Create(text string) { var task = Task{Text: text} engine.Insert(&task) } // 今回未使用 func (m TaskRepository) GetByID(id int) *Task { var task = Task{ID: id} has, _ := engine.Get(&task) if has { return &task } return nil } func (m TaskRepository) GetAll() Tasks { var task = Task{} var tasks = Tasks{} rows, err := engine.Rows(task) if err != nil{ return nil } defer rows.Close() for rows.Next() { err = rows.Scan(&task) tasks = append(tasks, task) } return tasks }
完成
これでまぁこんな感じの簡素なTODOアプリが出来ました。
あとは色々と肉付けして良い感じに仕上げられたら完璧ですね。