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アプリが出来ました。
あとは色々と肉付けして良い感じに仕上げられたら完璧ですね。