Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Go言語入門者が Webアプリケーション を作ってみた話 #devfest #gdgkyoto

18,644 views

Published on

This is talk about Starting with building web application with Golang

Published in: Technology
  • Be the first to comment

Go言語入門者が Webアプリケーション を作ってみた話 #devfest #gdgkyoto

  1. 1. Go言語入門者が Webアプリケーション を作ってみた話 @GDG Kyoto Dev Fest 2014 Pasta-K pastak@kmc.gr.jp
  2. 2. bit.ly/150ijMh
  3. 3. 自己紹介 • Pasta-K • Twitter / GitHub : @pastak • Blog : http://pastak.hatenablog.com • 京都大学工学部情報学科2回生 • オープンソースカンファレンス京都実行委員 • Go言語歴2ヶ月くらい
  4. 4. で、誰?
  5. 5. 京大マイコンクラブ広報
  6. 6. 学祭期間中(~月曜日) • 部員の作ったゲーム・音楽の展示 • 某白い犬の会社から来たスペシャルゲストが います
  7. 7. 昨年春 NHKのインタビューを受けた
  8. 8. たまこラブストーリー良かった
  9. 9. 本日!!
  10. 10. たまこ役 洲崎綾 トークショー in 京都大学
  11. 11. 落選したので来ました
  12. 12. がんばろう
  13. 13. Question
  14. 14. Go言語を
  15. 15. 聞いたことがある
  16. 16. 書いたことがある
  17. 17. Webアプリを 書いたことがある
  18. 18. Main Target
  19. 19. Go言語を
  20. 20. 聞いたことがある
  21. 21. 書いてみたい
  22. 22. (PerlとかRubyで) Webアプリを 書いたことがある
  23. 23. 方々
  24. 24. 話さないこと  • Go言語の導入方法 • Go言語の文法 • Go言語のイイトコ • Webアプリケーションのテスト • Webアプリケーションを作るうえでのベストプラクティ ス
  25. 25. 話すこと  • 自分がGo言語を書いてみようと思い立って書 いてみた方法を紹介します • 有識者の皆様におかれましては「もっと良 いのがあるよ」ってことがあれば後でこっ そり教えて下さい  • これからGo言語でWebアプリケーションを書 きたい人のとっかかりになれば幸いです
  26. 26. 話すこと • HTTPサーバを立ち上げる • Viewを実装する • Templateを利用する • MySQLを利用する • パッケージマネージャ
  27. 27. 目標
  28. 28. とにかくWebアプリを それっぽく作る
  29. 29. とにかくpackageを利用して Webアプリをそれっぽく作る
  30. 30. 今回の構成 • Web Application Framework • goji • Template Engine • ace • MySQL ORM • gorp • MySQL Migration • goose • Package Manager • gom
  31. 31. 1. HTTPサーバを立ち上げる
  32. 32. http packageを利用する package main ! import "http" ! func main() { http.HandleFunc("/", someFuncName) err := http.ListenAndServe(":9090", nil) if err != nil { panic(err) } } localhost:9090 で起動
  33. 33. github.com/zenazn/goji
  34. 34. 特徴(所感) かなり薄めのWAF  面倒見てくれるのはルーティングくらい  `http/net`との親和性
  35. 35. “Goji first of all attempts to be simple. It is of the Sinatra and Flask school of web framework design, and not the Rails/ Django one.” – github.com/zenazn/goji
  36. 36. さっきのをGojiで書いてみる package main ! import ( "github.com/zenazn/goji" "github.com/zenazn/goji/web" "net/http" ) ! func main() { goji.Get("/", someFuncName) goji.Serve() }
  37. 37. GETとかPOSTとか package main ! import ( "github.com/zenazn/goji" "github.com/zenazn/goji/web" "net/http" ) ! func main() { goji.Get("/", Index) goji.Get("/form", Form) goji.Get("/form/", http.RedirectHandler("/event/", 301)) goji.Post("/form/validate", Validate) goji.Serve() }
  38. 38. Hello Worldを出してみる package main ! import ( "fmt" "github.com/zenazn/goji" "github.com/zenazn/goji/web" "net/http" ) ! func hello(c web.C, w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "Hello, world") } ! func main() { goji.Get("/hello", hello) goji.Serve() } demo01
  39. 39. Sinatra style URL pattern package main ! import ( "fmt" "github.com/zenazn/goji" "github.com/zenazn/goji/web" "net/http" ) ! func hello(c web.C, w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "Hello, %s!", c.URLParams["name"]) } ! func main() { goji.Get("/hello/:name", hello) goji.Serve() } demo02
  40. 40. 2. Viewの実装  Templateの利用
  41. 41. Go言語の標準packageを使う package main ! import ( "fmt" "net/http" "html/template" ) ! type Member struct { Name string Message string } ! func main() { http.HandleFunc("/", handler) } ! func handler(w http.ResponseWriter, r *http.Request) { member := Member{"pastak", "こんにちは"} var t = template.Must(template.ParseFiles("template.html")) if err := t.Execute(w, member); err != nil { fmt.Println(err.Error()) } main.go
  42. 42. Go言語の標準packageを使う <h1> hello {{.Name}} </h1> <p>{{.Message}}</p> template.html demo03
  43. 43. if-else <h1> hello {{.Name}} </h1> <p> {{if .IsMorning}} おはようございます!!!!!!!!! {{else}} こんにちは {{end}} </p>
  44. 44. ifの中ではboolしか使えない (`html/template`の場合) <h1> hello {{.Name}} </h1> <p> <!-- 条件判断は出来ない --> {{if .Name == "John"}} You are John!!!!! {{else}} Who are you? {{end}} </p>
  45. 45. `text/template`はifの中で比 較が出来る <h1> hello {{.Name}} </h1> <p> {{if eq .Name "John"}} You are John!!!!! {{else}} Who are you? {{end}} </p>
  46. 46. for-loop ( range ) main.go type Person struct { Name string Email string } ! func main() { http.HandleFunc("/", handler) } ! func handler(w http.ResponseWriter, r *http.Request) { people := []*Person{ &Person{"john", "john@example.com"}, &Person{"mike", "mike@example.com"}, } var t = template.Must(template.ParseFiles("template.html")) _ = t.Execute(w, people) }
  47. 47. for-loop ( range ) <h1> Guest List </h1> <ul> {{range .}} template.html <li>Name: {{.Name}}</li> <ul> <li>Email : {{.Email}}</li> </ul> {{end}} </ul> demo04
  48. 48. github.com/yosssi/ace
  49. 49. 特徴(所感) Slimっぽく書ける “html/template”を利用している  {{if eq .Hoge “hoge”}}できない
  50. 50. “Ace is an HTML template engine for Go. This is inspired by Slim and Jade.” – github.com/yosssi/ace
  51. 51. Syntex example = doctype html html lang=en head title Hello Ace = css h1 { color: blue; } body h1#title {{.Title}} p.message {{.Message}} <!DOCTYPE html> <html lang=en> <head> <title> Hello ace</title> <style> h1 { color: blue; } </style> </head> <body> <h1 id="title">TitleText</h1> <p class=“message">Messages</ p> </body> </html>
  52. 52. 使ってみる func handler(w http.ResponseWriter, r *http.Request) { tpl, err := ace.Load("example", nil, nil) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } if err := tpl.Execute(w, map[string]string{"Msg": "Hello Ace"}); err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } } main.go
  53. 53. 使ってみる = doctype html html lang=en head title Ace example body h1 {{.Msg}} example.ace demo(時間があれば)
  54. 54. 3. MySQLを利用する
  55. 55. 出来れば、あんまり生のSQL は書きたくない・・・
  56. 56. そうだ
  57. 57. ORM
  58. 58. github.com/coopernurse/ gorp
  59. 59. gorpについて • MySQL, PostgreSQL, sqlite3 • ここではMySQLの例で説明します • 極力SQLを書かずにDBを扱える
  60. 60. table name: people name Type Null id Int Not Null Primary Key name String Not Null Email String Null
  61. 61. DBのカラムを表す 構造体を定義 type Person struct { Id int32 Name string Email sql.NullString // Nullを許容する場合はsql.Null****型を指定 }
  62. 62. データベースマッパーを作って 構造体と紐付ける db, _ := sql.Open("mymysql", "tcp:localhost:3306*dbName/user/passwd") dbmap := &gorp.DbMap{Db: db, Dialect: gorp.MySQLDialect{"InnoDB", “UTF8"} } t1 := dbmap.AddTableWithName(Person{},”people") .SetKeys(true, "Id") t1.ColMap("Id").Rename("id") t1.ColMap("Name").Rename("name") t1.ColMap("Email")
  63. 63. Select var people []Person dbmap.Select(&people, "select * from people order by id") // Select single row var person Person dbmap.SelectOne(&person, "select * from people where id=?", id) // Select by primary key obj, err := dbmap.Get(Person{}, 5) p := obj.(*Person)
  64. 64. Update / Insert / Delete alice := &Person{ 0, "Alice",sql.NullString{"alice@example.com", true} } err := dbmap.Insert(alice) ! alice2 := &Person{ 0, "Alice", sql.NullString{"alice@alice.net", true} } count, err := dbmap.Update(alice2) ! alice := &Person{1} count, err := dbmap.Delete(alice)
  65. 65. Migration
  66. 66. bitbucket.org/liamstask/ goose
  67. 67. dbディレクトリを作成 $ mkdir db $ cd db
  68. 68. 設定ファイルを書く development: driver: mymysql open: dbname/user/password ! production: driver: mymysql open: dbname/user/password db/dbconf.yml サンプル $GOPATH/src/bitbucket.org/liamstask/goose/db-sample/dbconf.yml
  69. 69. 設定の確認 Migrationの作成 $ goose status goose: status for environment 'development' $ goose create myapp sql db/migration/YYYYMMDDhhmmss_myapp.sql !が生成される
  70. 70. Migration用ファイルの編集 db/migration/YYYYMMDDhhmmss_myapp.sql -- +goose Up -- SQL in section 'Up' is executed when this migration is applied CREATE TABLE IF NOT EXISTS `people`( `id` INT NOT NULL AUTO_INCREMENT, `name` VARCHAR() NOT NULL, `Email` VARCHAR() PRIMARY KEY (`id`)) ENGINE = InnoDB; ! -- +goose Down -- SQL section 'Down' is executed when this migration is rolled back DROP TABLE `people`;
  71. 71. Migrationの実行 $ goose up Rollback $ goose down
  72. 72. 4. パッケージマネージャを利 用する
  73. 73. github.com/mattn/gom
  74. 74. ポイント • RubyのBundleっぽい操作感で使える
  75. 75. “The `go get` command is useful. But we want to fix the problem where package versions are different from the latest update. Are you going to do go get - tags=1.1 ..., go get -tag=0.3 for each of them? We want to freeze package version. Ruby's bundle is awesome.” – github.com/mattn/gom
  76. 76. Gomfileを編集 Gomfile gom 'github.com/zenazn/goji' gom 'github.com/zenazn/goji/web' gom 'github.com/yosssi/ace' gom 'github.com/coopernurse/gorp' gom 'bitbucket.org/liamstask/goose/cmd/goose' gom 'github.com/ziutek/mymysql/thrsafe' gom 'github.com/ziutek/mymysql/autorc' gom 'github.com/ziutek/mymysql/godrv'
  77. 77. Gomfileを編集 Gomfile ! gom 'github.com/yosssi/ace', :tag => 'tag_name' gom 'github.com/yosssi/ace', :branch => 'branch_name' gom 'github.com/yosssi/ace', :commit => 'commit_id'
  78. 78. gom install $ gom install installing … installing … $ ls _vendor _vendor "## bin $ &## goose "## pkg $ &## darwin_amd64 &## src "## bitbucket.org $ &## liamstask "## code.google.com &## github.com
  79. 79. run & build $ gom exec go run main.go // `go run` with packages $ gom build // `go build` with packages $ gom exec _vendor/bin/goose create myapp sql
  80. 80. まとめ • goji / ace / gorp with gom and goose なWebアプリ ケーションを作ってみる方法をざっと紹介しました • 作ってみたときのやつをGitHubに上げておくので良 かったら参考にしてみてください • (まだ上がってないので、上げたらブログに書きま す) • もっと良い知見がある人は是非教えて下さい!
  81. 81. 参考URLなど • Golang でのウェブ開発を考えてみる • http://qiita.com/voluntas/items/7af2f06d2688f649576f • astaxie/build-web-application-with-golang • https://github.com/astaxie/build-web-application-with-golang/tree/master/ja • golang製のDBマイグレーションツールgooseをMySQLで使ってみる • http://shusatoo.net/programming/golang/goose-mysql-migration/ • Keynote Template: Azusa • http://memo.sanographix.net/post/82160791768
  82. 82. Thank you  pastak@kmc.gr.jp

×