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

87
Go言語入門者が Webアプリケーション を作ってみた話 @GDG Kyoto Dev Fest 2014 Pasta-K [email protected]

Upload: shoot-morii

Post on 02-Jul-2015

13.683 views

Category:

Technology


5 download

DESCRIPTION

This is talk about Starting with building web application with Golang

TRANSCRIPT

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

Go言語入門者が

Webアプリケーション を作ってみた話

@GDG Kyoto Dev Fest 2014 Pasta-K

📧[email protected]

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

bit.ly/150ijMh

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

自己紹介• Pasta-K

• Twitter / GitHub : @pastak

• Blog : http://pastak.hatenablog.com

• 京都大学工学部情報学科2回生

• オープンソースカンファレンス京都実行委員

• Go言語歴2ヶ月くらい

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

で、誰?

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

京大マイコンクラブ広報

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

学祭期間中(~月曜日)• 部員の作ったゲーム・音楽の展示

• 某白い犬の会社から来たスペシャルゲストがいます

Page 7: Go言語入門者が Webアプリケーション を作ってみた話 #devfest #gdgkyoto
Page 8: Go言語入門者が Webアプリケーション を作ってみた話 #devfest #gdgkyoto
Page 9: Go言語入門者が Webアプリケーション を作ってみた話 #devfest #gdgkyoto
Page 10: Go言語入門者が Webアプリケーション を作ってみた話 #devfest #gdgkyoto
Page 11: Go言語入門者が Webアプリケーション を作ってみた話 #devfest #gdgkyoto

昨年春 NHKのインタビューを受けた

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

たまこラブストーリー良かった

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

本日!!

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

たまこ役 洲崎綾

トークショー in 京都大学

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

落選したので来ました

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

がんばろう

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

Question

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

Go言語を

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

聞いたことがある

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

書いたことがある

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

Webアプリを 書いたことがある

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

🎯Main Target🎯

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

Go言語を

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

聞いたことがある

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

書いてみたい

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

(PerlとかRubyで)

Webアプリを 書いたことがある

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

方々

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

話さないこと 🙊• Go言語の導入方法

• Go言語の文法

• Go言語のイイトコ

• Webアプリケーションのテスト

• Webアプリケーションを作るうえでのベストプラクティス

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

話すこと 👏

• 自分がGo言語を書いてみようと思い立って書いてみた方法を紹介します

• 有識者の皆様におかれましては「もっと良いのがあるよ」ってことがあれば後でこっそり教えて下さい 🙇

• これからGo言語でWebアプリケーションを書きたい人のとっかかりになれば幸いです

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

話すこと• HTTPサーバを立ち上げる

• Viewを実装する

• Templateを利用する

• MySQLを利用する

• パッケージマネージャ

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

目標

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

とにかくWebアプリを それっぽく作る

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

とにかくpackageを利用して

Webアプリをそれっぽく作る

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

今回の構成• Web Application Framework

• goji • Template Engine

• ace • MySQL ORM

• gorp • MySQL Migration

• goose • Package Manager

• gom

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

1. HTTPサーバを立ち上げる

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

http packageを利用するpackage main !import "http" !func main() { http.HandleFunc("/", someFuncName) err := http.ListenAndServe(":9090", nil) if err != nil { panic(err) } }

localhost:9090 で起動

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

github.com/zenazn/goji

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

特徴(所感)

かなり薄めのWAF  面倒見てくれるのはルーティングくらい  `http/net`との親和性

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

– github.com/zenazn/goji

“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.”

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

さっきのをGojiで書いてみる

package main !import ( "github.com/zenazn/goji" "github.com/zenazn/goji/web" "net/http" ) !func main() { goji.Get("/", someFuncName) goji.Serve() }

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

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() }

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

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

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

Sinatra style URL patternpackage 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

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

2. Viewの実装

 Templateの利用

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

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

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

Go言語の標準packageを使う

<h1> hello {{.Name}} </h1> <p>{{.Message}}</p>

template.html

demo03

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

if-else<h1> hello {{.Name}} </h1> <p> {{if .IsMorning}} おはようございます!!!!!!!!! {{else}} こんにちは {{end}} </p>

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

ifの中ではboolしか使えない (`html/template`の場合)

<h1> hello {{.Name}} </h1> <p> <!-- 条件判断は出来ない --> {{if .Name == "John"}} You are John!!!!! {{else}} Who are you? {{end}} </p>

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

`text/template`はifの中で比較が出来る

<h1> hello {{.Name}} </h1> <p> {{if eq .Name "John"}} You are John!!!!! {{else}} Who are you? {{end}} </p>

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

for-loop ( range )type Person struct { Name string Email string } !func main() { http.HandleFunc("/", handler) } !func handler(w http.ResponseWriter, r *http.Request) { people := []*Person{ &Person{"john", "[email protected]"}, &Person{"mike", "[email protected]"}, } var t = template.Must(template.ParseFiles("template.html")) _ = t.Execute(w, people) }

main.go

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

for-loop ( range )<h1> Guest List </h1> <ul> {{range .}} <li>Name: {{.Name}}</li> <ul> <li>Email : {{.Email}}</li> </ul> {{end}} </ul>

template.html

demo04

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

github.com/yosssi/ace

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

特徴(所感)

Slimっぽく書ける

“html/template”を利用している

 {{if eq .Hoge “hoge”}}できない

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

– github.com/yosssi/ace

“Ace is an HTML template engine for Go. This is inspired by Slim and Jade.”

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

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>

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

使ってみる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

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

使ってみる

= doctype html html lang=en head title Ace example body h1 {{.Msg}}

example.ace

demo(時間があれば)

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

3. MySQLを利用する

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

出来れば、あんまり生のSQLは書きたくない・・・

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

そうだ

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

ORM

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

github.com/coopernurse/gorp

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

gorpについて• MySQL, PostgreSQL, sqlite3

• ここではMySQLの例で説明します

• 極力SQLを書かずにDBを扱える

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

table name: people

name Type Null

id Int Not Null Primary Key

name String Not Null

Email String Null

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

DBのカラムを表す 構造体を定義

type Person struct { Id int32 Name string Email sql.NullString // Nullを許容する場合はsql.Null****型を指定 }

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

データベースマッパーを作って 構造体と紐付ける

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")

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

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)

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

Update / Insert / Deletealice := &Person{ 0, "Alice",sql.NullString{"[email protected]", true} } err := dbmap.Insert(alice) !alice2 := &Person{ 0, "Alice", sql.NullString{"[email protected]", true} } count, err := dbmap.Update(alice2) !alice := &Person{1} count, err := dbmap.Delete(alice)

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

Migration

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

bitbucket.org/liamstask/goose

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

dbディレクトリを作成

$ mkdir db$ cd db

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

設定ファイルを書く

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

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

設定の確認 Migrationの作成

$ goose statusgoose: status for environment 'development'$ goose create myapp sql

db/migration/YYYYMMDDhhmmss_myapp.sql !が生成される

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

Migration用ファイルの編集-- +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`;

db/migration/YYYYMMDDhhmmss_myapp.sql

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

Migrationの実行$ goose up

Rollback

$ goose down

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

4. パッケージマネージャを利用する

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

github.com/mattn/gom

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

ポイント• RubyのBundleっぽい操作感で使える

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

– github.com/mattn/gom

“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.”

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

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'

Gomfile

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

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'

Gomfile

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

gom install$ gom installinstalling …installing …$ ls _vendor_vendor"## bin$   &## goose"## pkg$   &## darwin_amd64&## src "## bitbucket.org $   &## liamstask "## code.google.com &## github.com

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

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

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

🎉まとめ🎉• goji / ace / gorp with gom and goose なWebアプリケーションを作ってみる方法をざっと紹介しました

• 作ってみたときのやつをGitHubに上げておくので良かったら参考にしてみてください

• (まだ上がってないので、上げたらブログに書きます)

• もっと良い知見がある人は是非教えて下さい!

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

参考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