SlideShare a Scribd company logo
How to create a Web
application for Golang
@yosuke_furukawa
@yosuke_furukawa
Node.jsユーザーグループ代表 / DeNA所属
Golang歴:2ヶ月くらい
作ったもの
!
- socket.io-go-emitter
- golang + angularjs で chat sample
- qiita アドベントカレンダーをスクレイピングす
るツール
Webアプリの作り方
Webアプリの作り方
net/httpでのwebサーバの建て方
DBアクセス/ORM
Web Application Framework
golangの勉強会を有志の数名
集めてDeNAでやってた
golangの勉強会をDeNAで
やってた
今回の話はそのまとめ
Goでweb applicationを
作る時に知っておいた方が
良いこと
net/httpでWebサーバをたててみる
https://gist.github.com/yosuke-furukawa/8309096
net/httpでWebサーバをたてる
package main	
!
import (	
"fmt"	
"net/http"	
"log"	
)	
!
func hello(w http.ResponseWriter, r *http.Request) {	
//fmt.Fprintfでwに入るものがクライアントに出力される	
fmt.Fprintf(w, "Hello World!")	
}	
!
func main() {	
// アクセスのルーティングを設定する	
http.HandleFunc("/", hello) 	
// portを指定して起動	
err := http.ListenAndServe(":9090", nil)	
if err != nil {	
log.Fatal("ListenAndServe: ", err)	
}	
}
net/httpでWebサーバをたてる
package main	
!
import (	
"fmt"	
"net/http"	
"log"	
)	
!
func hello(w http.ResponseWriter, r *http.Request) {	
//fmt.Fprintfでwに入るものがクライアントに出力される	
fmt.Fprintf(w, "Hello World!")	
}	
!
func main() {	
// アクセスのルーティングを設定する	
http.HandleFunc("/", hello) 	
// portを指定して起動	
err := http.ListenAndServe(":9090", nil)	
if err != nil {	
log.Fatal("ListenAndServe: ", err)	
}	
}	
HandleFuncでrouting
ListenAndServeでportを指定して起動
ListenAndServeの動き
func (srv *Server) Serve(l net.Listener) error {	
defer l.Close()	
var tempDelay time.Duration // how long to sleep on accept failure	
for {	
rw, e := l.Accept()	
if e != nil {	
if ne, ok := e.(net.Error); ok && ne.Temporary() {	
if tempDelay == 0 {	
tempDelay = 5 * time.Millisecond	
} else {	
tempDelay *= 2	
}	
if max := 1 * time.Second; tempDelay > max {	
tempDelay = max	
}	
log.Printf("http: Accept error: %v; retrying in %v", e, tempDelay)	
time.Sleep(tempDelay)	
continue	
}	
return e	
}	
tempDelay = 0	
c, err := srv.newConn(rw)	
if err != nil {	
continue	
}	
go c.serve()	
}	
}
ListenAndServeの動き
func (srv *Server) Serve(l net.Listener) error {	
defer l.Close()	
var tempDelay time.Duration // how long to sleep on accept failure	
for {	
rw, e := l.Accept()	
if e != nil {	
if ne, ok := e.(net.Error); ok && ne.Temporary() {	
if tempDelay == 0 {	
tempDelay = 5 * time.Millisecond	
} else {	
tempDelay *= 2	
}	
if max := 1 * time.Second; tempDelay > max {	
tempDelay = max	
}	
log.Printf("http: Accept error: %v; retrying in %v", e, tempDelay)	
time.Sleep(tempDelay)	
continue	
}	
return e	
}	
tempDelay = 0	
c, err := srv.newConn(rw)	
if err != nil {	
continue	
}	
go c.serve()	
}	
}
リスナーを通じてリクエストを受け取る
新しくコネクションのinstanceを作る
goroutineを起動し、リクエストを処理
ユーザーからのリクエストは全て新しいgoroutine
で行われ、互いに影響しない作りになっている
GoでRESTFul APIを作る
RESTFul APIおさらい
各URIがリソースを表す
このリソースを操作するため4つの
HTTPのメソッドを扱う
RESTFul APIおさらい
/users/:id
ユーザーを表現するためのリソース
GET, POST, PUT, DELETE
HTTP methodを使って操作する
RESTFul APIを作る
package main	
!
import (	
"fmt"	
"github.com/drone/routes"	
"net/http"	
)	
!
// GET用のHandler	
func getuser(w http.ResponseWriter, r *http.Request) {	
params := r.URL.Query()	
id := params.Get(":id")	
fmt.Fprintf(w, "you are get user %s", id)	
}	
// PUT, DELETE, POST用の…	
!
func main() {	
mux := routes.New()	
// GET, PUT, DELETE, POST 用のハンドラー関数をroutingする	
mux.Get("/users/:id", getuser)	
mux.Put("/users/:id", modifyuser)	
mux.Del("/users/:id", deleteuser)	
mux.Post("/users/", adduser)	
http.Handle("/", mux)	
http.ListenAndServe(":9090", nil)	
}
RESTFul APIを作る
package main	
!
import (	
"fmt"	
"github.com/drone/routes"	
"net/http"	
)	
!
// GET用のHandler	
func getuser(w http.ResponseWriter, r *http.Request) {	
params := r.URL.Query()	
id := params.Get(":id")	
fmt.Fprintf(w, "you are get user %s", id)	
}	
// PUT, DELETE, POST用の…	
!
func main() {	
mux := routes.New()	
// GET, PUT, DELETE, POST 用のハンドラー関数をroutingする	
mux.Get("/users/:id", getuser)	
mux.Put("/users/:id", modifyuser)	
mux.Del("/users/:id", deleteuser)	
mux.Post("/users/", adduser)	
http.Handle("/", mux)	
http.ListenAndServe(":9090", nil)	
}	
drone/routesとかgowebとかの
ルーティング用の
3rd modulesを使う
大したことはやってないので、
net/httpだけで頑張る事も可能だが、
:idから始まる文字のパースと
methodによるrouting処理が面倒なら
こういうモジュール使うのもあり。
これだけで簡単なREST APIは作れる
DBアクセス
https://gist.github.com/yosuke-furukawa/8552841
DBアクセス
package main	
!
import (	
"database/sql"	
_ "github.com/go-sql-driver/mysql"	
"log"	
)	
!
func main() {	
  // sql.Open 第一引数にdriverの種類、第二引数に接続アドレスを指定、ここではhello
に接続することを宣言。	
db, err := sql.Open("mysql",	
"root@tcp(127.0.0.1:3306)/hello")	
// errがあればそれを表示	
if err != nil {	
log.Fatal(err)	
}	
// deferで関数の終わりにそれをclose	
defer db.Close()	
}
DBアクセス
package main	
!
import (	
"database/sql"	
_ "github.com/go-sql-driver/mysql"	
"log"	
)	
!
func main() {	
  // sql.Open 第一引数にdriverの種類、第二引数に接続アドレスを指定、ここではhello
に接続することを宣言。	
db, err := sql.Open("mysql",	
"root@tcp(127.0.0.1:3306)/hello")	
// errがあればそれを表示	
if err != nil {	
log.Fatal(err)	
}	
// deferで関数の終わりにそれをclose	
defer db.Close()	
}
sql.OpenでDBアクセス開始
SELECT操作
var (	
id int	
name string	
)	
// db.PrepareでPreparedStatement実行	
stmt, err := db.Prepare("select id, name from users where id = ?")	
if err != nil {	
log.Fatal(err)	
}	
// statementのClose忘れずに。	
defer stmt.Close()	
// stmt.QueryでQueryを実行	
rows, err := stmt.Query(1);	
for rows.Next() {	
err := rows.Scan(&id, &name)	
if err != nil {	
log.Fatal(err)	
}	
log.Println(id, name)	
}	
defer rows.Close();
SELECT操作
var (	
id int	
name string	
)	
// db.PrepareでPreparedStatement実行	
stmt, err := db.Prepare("select id, name from users where id = ?")	
if err != nil {	
log.Fatal(err)	
}	
// statementのClose忘れずに。	
defer stmt.Close()	
// stmt.QueryでQueryを実行	
rows, err := stmt.Query(1);	
for rows.Next() {	
err := rows.Scan(&id, &name)	
if err != nil {	
log.Fatal(err)	
}	
log.Println(id, name)	
}	
defer rows.Close();
db.PrepareでSQL実行する
stmt.QueryでQueryを実行
ここでは、id=1を実行
INSERTとかUPDATEとかDELETEとか
!
stmt, err := db.Prepare("INSERT INTO users(id, name) VALUES(?, ?)")	
if err != nil {	
log.Fatal(err)	
}	
res, err := stmt.Exec(2, "haruyama")	
if err != nil {	
log.Fatal(err)	
}
INSERTとかUPDATEとかDELETEとか
!
stmt, err := db.Prepare("INSERT INTO users(id, name) VALUES(?, ?)")	
if err != nil {	
log.Fatal(err)	
}	
res, err := stmt.Exec(2, "gopher")	
if err != nil {	
log.Fatal(err)	
}
stmt.Execで更新系のQueryを発行する
ここまでで簡単なDBアクセスと永続化はできる
ORM
こんだけある…
http://present.go-steel-programmers.org/talk-review-orms/gsp-go-orms.slide#1
あんまり試せてない…
シンプルでquery builderっぽいgorpか
gormが良さそうだけど、API的には
どれも有意差はない
Web Application Frameworks
https://gist.github.com/yosuke-furukawa/8816249
TL;DR
net/http
martini, beego
revel, falcore
goweb,
drone/routes
gorilla/negroni
need simple
REST Framework
toolkit/compatible with net/http
Sinatra/Express like
Fullstack RoR like
martini
!
• フルスタックフレームワーク
• martiniがsinatraならこっちはRoR, Play
Framework、ちなみに初期ページすごくPlayっぽい
• 中にmail senderやwebsocketも組み込まれてる
• ミドルウェアもフィルターという概念を使うことで使
える
• コード変更を検知して自動リロード/テストフレーム
ワークが中にある、など開発にも便利
Falcore
• 我らがngmoco製、最近はメンテをfitstarさんに
譲っている様子
• フルスタックフレームワーク
• HUPを送ったら自動でprocessをforkして子プロ
セスがreadyになったら自分を殺す動きをする
• これにより、hot restartが可能になっている
beego
• revelほど高機能ではないが、一応フルスタックフレームワーク
• ドキュメントが超親切
• beego/ORMをサポートし、MVCに

特化している
• 中国では採用実績あり?
!
!
!
!
!
martini
!
!
• 人気がある(github/star的な意味で)
• すごくSinatra/Expressライク
• 基本的な機能しかコアには存在せず、ミドル
ウェアで機能拡張する
• 豊富なミドルウェアが存在している。
• ただし、作者はあんまり推してない。
martini
!
!
• Martiniの作者がHTTP serverをより簡易的に、イディ
オム的に扱えるようにするために開発したライブラリ
• 正確にはフレームワークではなく、ライブラリ群
• 今後Martiniの代わりにスタンダードになる可能性があ
るかも。
!
!
martini
!
!
• こちらも正確にはツールキット
• router, secure session, websocket等、まぁWebアプリ作
るには使うよねっていうのが ってる。
• isucon っていうweb アプリ高速化チューニングコンテスト
で使われてる。
• 他にも実はrevelの中で使われてたりと汎用性高い。
!
WAFまとめ
net/http
martini, beego
revel, falcore
goweb,
drone/routes
gorilla/negroni
need simple
REST Framework
toolkit/compatible with net/http
Sinatra/Express like
Fullstack RoR like
まとめ
• Webサーバの建て方とnet/httpの

基礎的な話
• DBアクセスの方法
• Web Application Framework

まとめ
今後やりたい事
今後やりたい事
Go + socket.io で死ぬ予定

More Related Content

What's hot (19)

FINAL FANTASY Record Keeperを支えたGolang by Yoshiki Shibukawa, has 35 slides with 31132 views.
FINAL FANTASY Record Keeperを支えたGolangFINAL FANTASY Record Keeperを支えたGolang
FINAL FANTASY Record Keeperを支えたGolang
Yoshiki Shibukawa
35 slides31.1K views
GoでMinecraftっぽいの作る by 京大 マイコンクラブ, has 56 slides with 25295 views.
GoでMinecraftっぽいの作るGoでMinecraftっぽいの作る
GoでMinecraftっぽいの作る
京大 マイコンクラブ
56 slides25.3K views
Go言語のスライスを理解しよう by Yasutaka Kawamoto, has 60 slides with 31360 views.
Go言語のスライスを理解しようGo言語のスライスを理解しよう
Go言語のスライスを理解しよう
Yasutaka Kawamoto
60 slides31.4K views
GAE/GoでWebアプリ開発入門 by Takuya Ueda, has 50 slides with 8345 views.
GAE/GoでWebアプリ開発入門GAE/GoでWebアプリ開発入門
GAE/GoでWebアプリ開発入門
Takuya Ueda
50 slides8.3K views
Hubotを使ってbotをつくろう! by Daisuke Kikuchi, has 20 slides with 3589 views.
Hubotを使ってbotをつくろう!Hubotを使ってbotをつくろう!
Hubotを使ってbotをつくろう!
Daisuke Kikuchi
20 slides3.6K views
hubotで快適BOT生活 by Kazufumi Otani, has 51 slides with 24006 views.
hubotで快適BOT生活 hubotで快適BOT生活
hubotで快適BOT生活
Kazufumi Otani
51 slides24K views
Go言語でBot開発やってみた by Akihiko Horiuchi, has 16 slides with 3727 views.
Go言語でBot開発やってみたGo言語でBot開発やってみた
Go言語でBot開発やってみた
Akihiko Horiuchi
16 slides3.7K views
実践Go ツールの作成から配布まで by Yusuke Miyake, has 39 slides with 7706 views.
実践Go ツールの作成から配布まで実践Go ツールの作成から配布まで
実践Go ツールの作成から配布まで
Yusuke Miyake
39 slides7.7K views

Similar to ヒカルのGo 資料 Webアプリケーションの作り方 (20)

Microsoft Graph API Library for Go by yaegashi, has 27 slides with 4570 views.
Microsoft Graph API Library for GoMicrosoft Graph API Library for Go
Microsoft Graph API Library for Go
yaegashi
27 slides4.6K views
後期02 by Takenori Nakagawa, has 45 slides with 524 views.
後期02後期02
後期02
Takenori Nakagawa
45 slides524 views
Google Apps Scirpt勉強会 #1 by ikikko , has 18 slides with 2059 views.
Google Apps Scirpt勉強会 #1Google Apps Scirpt勉強会 #1
Google Apps Scirpt勉強会 #1
ikikko
18 slides2.1K views
Ruby向け帳票ソリューション「ThinReports」の開発で知るOSSの威力 by ThinReports, has 98 slides with 6745 views.
Ruby向け帳票ソリューション「ThinReports」の開発で知るOSSの威力Ruby向け帳票ソリューション「ThinReports」の開発で知るOSSの威力
Ruby向け帳票ソリューション「ThinReports」の開発で知るOSSの威力
ThinReports
98 slides6.7K views
Express Web Application Framework by LearningTech, has 18 slides with 675 views.
Express Web Application FrameworkExpress Web Application Framework
Express Web Application Framework
LearningTech
18 slides675 views
Firefox5+HTML5×5 by dynamis , has 84 slides with 2090 views.
Firefox5+HTML5×5Firefox5+HTML5×5
Firefox5+HTML5×5
dynamis
84 slides2.1K views
APIMeetup 20170329_ichimura by Tomohiro Ichimura, has 80 slides with 861 views.
APIMeetup 20170329_ichimuraAPIMeetup 20170329_ichimura
APIMeetup 20170329_ichimura
Tomohiro Ichimura
80 slides861 views

Slideshows for you (20)

How Game Developers Reach New Customers with Twitch by Amazon Web Services, has 15 slides with 9543 views.
How Game Developers Reach New Customers with Twitch How Game Developers Reach New Customers with Twitch
How Game Developers Reach New Customers with Twitch
Amazon Web Services
15 slides9.5K views
Big Data Case Study on Walmart by JainamParikh3, has 15 slides with 8456 views.
Big Data Case Study on WalmartBig Data Case Study on Walmart
Big Data Case Study on Walmart
JainamParikh3
15 slides8.5K views
Product Owner vs Product Manager by AgileSparks, has 70 slides with 89042 views.
Product Owner vs Product ManagerProduct Owner vs Product Manager
Product Owner vs Product Manager
AgileSparks
70 slides89K views
Digital Transformation Templates.ppt by Olusegun Mosugu, has 66 slides with 2789 views.
Digital Transformation Templates.pptDigital Transformation Templates.ppt
Digital Transformation Templates.ppt
Olusegun Mosugu
66 slides2.8K views
Lean Startup for Agile Product Management by Proyectalis / Improvement21, has 78 slides with 137457 views.
Lean Startup for Agile Product ManagementLean Startup for Agile Product Management
Lean Startup for Agile Product Management
Proyectalis / Improvement21
78 slides137.5K views
A step by-step guide to calculating customer lifetime value by Geoff Fripp, has 18 slides with 115592 views.
A step by-step guide to calculating customer lifetime valueA step by-step guide to calculating customer lifetime value
A step by-step guide to calculating customer lifetime value
Geoff Fripp
18 slides115.6K views
Data analytics by BindhuBhargaviTalasi, has 18 slides with 4023 views.
Data analyticsData analytics
Data analytics
BindhuBhargaviTalasi
18 slides4K views
intro chatGPT workshop.pdf by peterpur, has 20 slides with 2724 views.
intro chatGPT workshop.pdfintro chatGPT workshop.pdf
intro chatGPT workshop.pdf
peterpur
20 slides2.7K views

ヒカルのGo 資料 Webアプリケーションの作り方