ルーティングとORMには以下のものを使わせてもらいます。
goは好きなものを選択して作れるのがよいですね。
gojiはシンプルで高速なWAFです。
middlewareを足すことで機能を追加することができます。
ORMは他にcoopernurse/gorpも有名らしいですが、gormのほうがドキュメントが充実しており機能も豊富なのでgormを使ってみます。
goapp get github.com/zenazn/goji
goapp get github.com/jinzhu/gorm
テーブル作成
cakephpのチュートリアルのサンプルを拝借しました。
1 2 3 4 5 6 7 8
| CREATE TABLE `posts` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `title` varchar(50) DEFAULT NULL, `body` text, `created_at` datetime DEFAULT NULL, `updated_at` datetime DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=utf8
|
createdとmodifiedの部分はgormに合わせて変更しました。
サンプルの内容も入れておきます。
違うテーブル名やカラム名でもマッピングできるようですが、
最初ならマイグレーションファイル作るのがよさそうです。
http://qiita.com/masahikoofjoyto/items/b2e6c2cad447e48f91ee
対応するmodel
1 2 3 4 5 6 7
| type Post struct { Id int Title string Body string CreatedAt time.Time UpdatedAt time.Time }
|
ルーティング
簡単にルーティングを作成します。
gojiはgaeから使う場合はhttp.Handle("/", goji.DefaultMux)
とします。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| var db gorm.DB func init() { db, _ = gorm.Open("mysql", "root@cloudsql(projectId:CouldSQLInstanceId)/dbname?charset=utf8&parseTime=True&loc=Japan") posts := web.New() goji.Handle("/posts/*", posts) posts.Use(middleware.SubRouter) posts.Get("/", View) posts.Get("/:id", ViewById) posts.Post("/edit/", Update) http.Handle("/", goji.DefaultMux) }
|
datetimeのマッピング時に標準時が使用されるため接続文字列にloc=Japanが必要でした。
posts以下をまとめるにはSubRouterというmiddlewareを使用します。
一覧をjsonで出力
1 2 3 4 5 6 7 8 9
| func View(c web.C, w http.ResponseWriter, r *http.Request) { posts := []Post{} db.Find(&posts) w.Header().Set("Content-Type", "application/json; charset=utf-8") encoder := json.NewEncoder(w) encoder.Encode(&posts) }
|
一件取得
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| func ViewById(c web.C, w http.ResponseWriter, r *http.Request) { post := Post{} id, err := strconv.Atoi(c.URLParams["id"]) if err != nil { http.Error(w, err.Error(), http.StatusBadRequest) return } db.Find(&post, id) w.Header().Set("Content-Type", "application/json; charset=utf-8") encoder := json.NewEncoder(w) encoder.Encode(&post) }
|
jsonをpostして新規追加と編集
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| func Update(c web.C, w http.ResponseWriter, r *http.Request) { post := Post{} err := json.NewDecoder(r.Body).Decode(&post) if err != nil { http.Error(w, err.Error(), http.StatusBadRequest) return } postForSave := Post{} db.First(&postForSave, post.Id) postForSave.Title = post.Title postForSave.Body = post.Body db.Save(&postForSave) }
|
そのままSaveできれば便利だったのですが、created_atが消えてしまいました。
ちょっといまいちな感じになっています。
{"Id":2,"Title":"タイトル編集","Body":"本文編集"}
Idありでpostすると編集され、
{"Title":"タイトル新規追加","Body":"本文新規追加"}
Idがないと新規追加されます。
テストやDB側が複雑になった場合の不安はありますが、
簡単なものであればすぐに作れそうです。