go言語で作る webアプリ@gocon 2013 spring
TRANSCRIPT
Go言語で作る
Webアプリ- RESTful APIを作ろう -
2013/4/13(Sat.)@GoCon 2013 spring
自己紹介
上田拓也新卒1年目
twitter : @tenntennblog: http://u.hinoichi.net
目標と対象
【目標】● net/httpパッケージを知る● gowebの基本的な使い方を知る
【対象】● Go言語初心者● goweb知らない人
アジェンダ
● Webサーバを作ろう○ net/httpパッケージ
● RESTful APIを作ろう○ RESTful APIとは?○ gowebの使い方
● おまけ
Webサーバを作ろう
はじめに
● ドキュメントを軽く見ながら聞いて下さい○ http://golang.org/pkg/net/http○ http://godoc.org/github.
com/stretchrcom/goweb/goweb
Go言語でhttpリクエストをハンドル
ブラウザ
サーバサイド
80番ポート
クライアントサイド
http.ServerListenAndServe@80ポート
http.Handlerハンドル
http.Server型
type Server struct { Addr string Handler Handler ReadTimeout time.Duration WriteTimeout time.Duration MaxHeaderBytes int TLSConfig *tls.Config}
http.Server型
● type Server struct○ func (srv *Server) ListenAndServe() error○ func (srv *Server) ListenAndServeTLS(certFile,
keyFile string) error○ func (srv *Server) Serve(l net.Listener) error
http.Handler型
type Handler interface {ServeHTTP(ResponseWriter, *Request)
}
複数のハンドラを設定する
http.ServerListenAndServe@80ポート
http.Handler
http.Handler
http.Handler
/aaa
/bbb
/zzz
http.ServeMuxハンドル
http.ServeMux型
type struct ServeMux{}// 指定したパタンでハンドラを登録
func (mux *ServeMux) Handle(pattern string, handler Handler)// 指定したパタンでハンドラ関数を登録
func (mux *ServeMux) HandleFunc(pattern string, handler func(ResponseWriter, *Request)// http.Handlerの実装
func (mux *ServeMux) ServeHTTP(w ResponseWriter, r *Request)
http.Handleの実装めんどい
● ServeMux.HandleFuncを使えばいい● HandlerFuncを使って、関数にhttp.Handlerを
実装させている
http.HandlerFunc型
type HandlerFunc func(ResponseWriter, *Request)
// src/pkg/net/http/server.goで実装
// http.Handlerを実装
func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) {
f(w, r)}
http.ServeMux作るのめんどい
● http.DefaultServeMuxというグローバル変数
がある
● http.Handleやhttp.HandleFuncはhttp.
DefaultServeMuxのメソッドのラッパー
● ハンドラが明示されないと、http.
DefaultServerMuxが使用される
簡単な例:hello, http!!
func main() {f := func(w http.ResponseWriter, r *http.
Request) {fmt.Fprintf(w, "hello, http!!")
}
http.HandleFunc("/", f)http.ListenAndServe(":8080", nil)
}
https://github.com/golang-samples/http/tree/master/handlefunc
簡単な例:静的ファイル
func main() {
// static以下のファイルを提供
http.Handle("/", http.FileServer(http.Dir("static")))http.ListenAndServe(":8080", nil)
}
https://github.com/golang-samples/http/tree/master/fileserv
DEMO1
RESTful APIを作ろう
RESTful APIとは?
● 明示的にHTTPメソッドを使う○ POST, GET, PUT, DELETE ○ CRUDと対応
● ステートレスにする○ 状態を保存しない
● ディレクトリ構造に似たURI○ /api/persons/10
● XML、JSONなどを転送する○ リクエストやレスポンスにXMLやJSONを使用
Go言語でRESTful APIを作る
● URIだけではなく、httpのメソッドでも分岐したい
● JSONやXMLで来たリクエストを簡単にオブジェクトにしたい
● JSONやXMLでレスポンスを返すのを簡単にしたい
GoWebがあるよ!
GoWebってなに?
● RESTful APIを作るためのライブラリ○ https://github.com/stretchrcom/goweb
● 細かいルーティング管理できる● Controllerを作り、POST, GET, PUT, DELETE
などの単位でハンドリング● JSONやXMLをリクエストから作れる● レスポンスを簡単に作れる
○ 良く使うステータスコード○ JSONやXML
GoWebの構造
:HttpHandler
ServeHTTP
DefaultRouteManager:RouteManager
GetMathingRoute()
routes
:Controller
route.Controller.HandleRequest()
loop:routesif:route.DoesMatchContext
GoWebの簡単な使い方
func main() {handler := func(c *goweb.Context) {
name := c.PathParams["name"]animal := c.PathParams["animal"]fmt.Fprintf(c.ResponseWriter, "Hey %s,
your favorite animal is a %s", name, animal)}goweb.MapFunc("/people/{name}/animals/
{animal}", handler)goweb.ListenAndServe(":8080")
}https://github.com/golang-samples/goweb/tree/master/mapfunc
GoWebの簡単な使い方 RESTful API// REST用のコントローラー
type MyController struct {}
HTTPメソッド URI例 実装するメソッド
POST /api/ RestCreater.Create
GET /api/ RestManyReader.ReadMany
GET /api/123 RestReader.Read
PUT /api/ RestManyUpdater.UpdateMany
PUT /api/123 RestUpdater.Update
DELETE /api/ RestManyDeleter.DeleteMany
DELETE /api/123 RestDeleter.Delete※必要なものだけ、実装する
GoWebの簡単な使い方 RESTful API// POSTをハンドリングする
func (cr *MyController) Create(cx *goweb.Context) { fmt.Fprintf(cx.ResponseWriter, "Create new resource")}
GoWebの簡単な使い方 RESTful API// GETをハンドリング(id指定)
func (cr *MyController) Read(id string, cx *goweb.Context) { fmt.Fprintf(cx.ResponseWriter, "Read resource %s", id)}
// GETをハンドリング(id指定なし)
func (cr *MyController) ReadMany(cx *goweb.Context) { fmt.Fprintf(cx.ResponseWriter, "Read many resources")}
GoWebの簡単な使い方 RESTful API// PUTをハンドリング(id指定)
func (cr *MyController) Update(id string, cx *goweb.Context) { fmt.Fprintf(cx.ResponseWriter, "Update resource %s", id)}
// PUTをハンドリング(id指定なし)
func (cr *MyController) UpdateMany(cx *goweb.Context) { fmt.Fprintf(cx.ResponseWriter, "Update many resources")}
GoWebの簡単な使い方 RESTful API// DELETEをハンドリング(id指定)
func (cr *MyController) Delete(id string, cx *goweb.Context) { fmt.Fprintf(cx.ResponseWriter, "Delete resource %s", id)}
// DELETEをハンドリング(id指定なし)
func (cr *MyController) DeleteMany(cx *goweb.Context) { fmt.Fprintf(cx.ResponseWriter, "Delete many resources")}
GoWebの簡単な使い方 RESTful APIfunc main() {
controller := new(MyController)goweb.MapRest("/api", controller)goweb.ListenAndServe(":8080")
}
https://github.com/golang-samples/goweb/tree/master/rest
DEMO2
まとめ
● Go言語でWebサーバ作るの簡単!○ net/httpパッケージを使う
● gowebを使えばRESTful API作るの簡単!○ 各HTTPメソッドとURIに対応したメソッドを実装
話きれなかったこと
● テンプレートエンジン○ html/template, text/template
● テスト○ net/http/httptest
● FastCGI○ net/http/fcgi○ nginxなどで使用
● gowebの具体的な使用例○ AngularJSから使う○ https://github.com/golang-
samples/goweb/tree/master/diary
おまけ
Go言語のサンプル置き場
● https://github.com/golang-samples● みんなでサンプルを増やそう!
○ すでにあるパッケージはフォークしてもOK!○ メンバーに加わって、新たにパッケージを追加しても
OK!
Go言語が使えるエディタ/IDE
● https://code.google.com/p/go-wiki/wiki/IDEsAndTextEditorPlugins
● Vim● Emacs● Sublime Text● LiteIDE● Goclipse(Eclipse)● Goworks(Netbeans)
ご清聴ありがとうございました