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

PDF
Go言語入門者が Webアプリケーション を作ってみた話 #devfest #gdgkyoto
PDF
Go言語によるwebアプリの作り方
PDF
Ginとbindataで作るシングルバイナリWebApp
PDF
Go言語で作る webアプリ@gocon 2013 spring
PDF
GoによるWebアプリ開発のキホン
PDF
Firefox Add-on SDK 入門
PDF
Goでかんたんソースコードの静的解析
PDF
今日から始める Go言語 と appengine
Go言語入門者が Webアプリケーション を作ってみた話 #devfest #gdgkyoto
Go言語によるwebアプリの作り方
Ginとbindataで作るシングルバイナリWebApp
Go言語で作る webアプリ@gocon 2013 spring
GoによるWebアプリ開発のキホン
Firefox Add-on SDK 入門
Goでかんたんソースコードの静的解析
今日から始める Go言語 と appengine

What's hot (19)

PPTX
FINAL FANTASY Record Keeperを支えたGolang
PDF
GoでMinecraftっぽいの作る
KEY
Go言語のスライスを理解しよう
PDF
GAE/GoでWebアプリ開発入門
PPTX
Hubotを使ってbotをつくろう!
KEY
hubotで快適BOT生活
PDF
Go言語でBot開発やってみた
PDF
実践Go ツールの作成から配布まで
PDF
Go入門
PDF
Go MobileでAndroidアプリ開発
PPTX
node-gypを使ったネイティブモジュールの作成
PDF
Python × Herokuで作る 雑談slack bot
PDF
hubot-slack v4移行時のハマりどころ #hubot_chatops
PDF
条件式評価器の実装による管理ツールの抽象化
PDF
Goで言語処理系(の途中まで)を作ろう
PDF
配布用Dotcloudによるすぐ始めるtwitterwebアプリ開発#twtr hack
PDF
メルカリ・ソウゾウでは どうGoを活用しているのか?
PDF
Hubotをはじめる
PDF
Goにおける静的解析と製品開発への応用
FINAL FANTASY Record Keeperを支えたGolang
GoでMinecraftっぽいの作る
Go言語のスライスを理解しよう
GAE/GoでWebアプリ開発入門
Hubotを使ってbotをつくろう!
hubotで快適BOT生活
Go言語でBot開発やってみた
実践Go ツールの作成から配布まで
Go入門
Go MobileでAndroidアプリ開発
node-gypを使ったネイティブモジュールの作成
Python × Herokuで作る 雑談slack bot
hubot-slack v4移行時のハマりどころ #hubot_chatops
条件式評価器の実装による管理ツールの抽象化
Goで言語処理系(の途中まで)を作ろう
配布用Dotcloudによるすぐ始めるtwitterwebアプリ開発#twtr hack
メルカリ・ソウゾウでは どうGoを活用しているのか?
Hubotをはじめる
Goにおける静的解析と製品開発への応用
Ad

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

PDF
Goでwebアプリを開発してみよう
PDF
【とらラボLT】go言語でのweb apiの作り方3選
PPTX
Gunosy Go lang study #6 net http url
PDF
golangでREST Serverを作ってみました。
PDF
Let's make rest server by golang
PDF
Go言語によるWebアプリケーション開発
PDF
らくちん Go言語
PDF
GoCon2016 spring 自作Webフレームワーク uconを作った話
PDF
今日から始めるGopher - スタートGo #0 @GDG名古屋
PDF
SocketStream入門
PPTX
REST API、gRPC、GraphQL 触ってみた【2023年12月開催勉強会資料】
PPTX
EchoyaGinhanazeSu_inoka.pptx
PDF
Go1.8 for Google App Engine
PDF
エキスパートGo
PDF
みんなでWAIWAI Webアプリ
PDF
[Golang] Go言語でサービス作ってる話
PDF
できる!スマホアプリ:Webからはじまるアプリ for CMU16
PDF
gRPC入門
PDF
20130824 Lightweight Language "Go" @LL matsuri
PDF
densan2014-late01
Goでwebアプリを開発してみよう
【とらラボLT】go言語でのweb apiの作り方3選
Gunosy Go lang study #6 net http url
golangでREST Serverを作ってみました。
Let's make rest server by golang
Go言語によるWebアプリケーション開発
らくちん Go言語
GoCon2016 spring 自作Webフレームワーク uconを作った話
今日から始めるGopher - スタートGo #0 @GDG名古屋
SocketStream入門
REST API、gRPC、GraphQL 触ってみた【2023年12月開催勉強会資料】
EchoyaGinhanazeSu_inoka.pptx
Go1.8 for Google App Engine
エキスパートGo
みんなでWAIWAI Webアプリ
[Golang] Go言語でサービス作ってる話
できる!スマホアプリ:Webからはじまるアプリ for CMU16
gRPC入門
20130824 Lightweight Language "Go" @LL matsuri
densan2014-late01
Ad

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