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.
堀内 晨彦
@hico_horiuchi
Ginとbindataで作る
シングルバイナリWebApp
自己紹介
Akihiko Horiuchi
香川大学 修士2年
bit.ly/hiconyan
研究室のインフラと掃除担当
github.com/sai-lab/mouryou
github.com/sai-lab/mouryou-web
Em...
シェルスクリプトマガジン!
●  「香川大学SLPからお届け!」シリーズ
○  Vol. 33 Go言語とMithril.jsでWebアプリ開発 バックエンド編
○  Vol. 34 Go言語とMithril.jsでWebアプリ開発 フロントエ...
GoでWebAppを作るメリット
●  シングルバイナリ でデプロイ
○  コンパイルしたバイナリをアップロードするだけ
○  ライブラリのインストールなどが要らない
○  コンテナ や マイクロサービス との親和性が高そう
●  インタプリタ...
GoでWebAppを作るデメリット
●  Webフレームワーク 戦国時代
○  シンプル < Gin < Goji < Martini < Revel < フルスタック
○  Railsのようなデファクトスタンダードが決まっていない
●  OR...
デモンストレーション
「kakuzuke」
http://kakuzuke.hiconyan.com/
https://github.com/hico-horiuchi/kakuzuke
16/01/23 6
デモンストレーション
「yosage」
http://yosage.hiconyan.com/
https://github.com/hico-horiuchi/yosage
16/01/23 7
オススメのパッケージ
●  github.com/gin-gonic/gin
○  構造体をJSONで返せるのでAPIサーバとして使う
●  github.com/yosssi/ace
○  Slimライクに html/template を書け...
僕が考えた最強のディレクトリ構成
16/01/23 9
webapp/
├ app/
│ ├ controllers/ 
Mithril.jsのコントローラ
│ ├ views/ 
Mithril.jsのビュー
│ └ app.js 
Mith...
今回のポイント・工夫
●  GinでMVCデザインのAPIサーバを作成
○  これまでRails + Grapeで開発していたので
○  Viewはヘッダー・ナビゲーションバー・フッターのみ
●  フロントエンドはMithril.jsで作成
○...
GinでAPIサーバを作成(1)
●  モデルを構造体で定義
○  lib/models/user.go
○  `json:"login"` のようなタグ(アノテーション)を付ける
16/01/23 11
type User struct {
...
GinでAPIサーバを作成(2)
●  コントローラでJSONを返却
○  lib/controllers/ranking_controller.go
○  c.JSON で構造体をJSONとして返せる
16/01/23 12
type Ran...
Aceでテンプレートを作成
●  ヘッダーとナビゲーションバーのみ
○  lib/view/layout.ace
16/01/23 13
= doctype html
html lang="en"
head
title kakuzuke
lin...
bindataでアセットをバイナリ化
●  app/ と assets/ と lib/views/ をバイナリ化
○  Makefile で変換するようにした
○  go-bindata-assetfs を使うと http.FileSystem...
Ginでbindataを配信
●  ここがちょっと面倒
○  router.go
○  Ginでは http.FileServer ではなく static.Serve を使う
○  http.FileSystem も使えないので BinaryF...
freshでビルドしながら開発
●  ソースコードの変更を検知してリビルド
○  変更の反映にコンパイルが必要なGoの強い味方
○  JavaScriptだとGrantとかgulpみたいな感じ?
○  監視する拡張子と間隔を設定できる
16/0...
まとめ・おわりに
●  Ginとbindataで シングルバイナリ を実現
○  kakuzukeだと最終的なバイナリが 8MB 程になる
○  bindata_assetfs.go で 2MB 、Minifyすれば軽量化できそう
●  Gom...
Golang勉強会 in Kagawa
「Golang勉強会 in Kagawa」を開催します!
●  日時 :2016年2月27日(土) 13:00∼18:00
●  場所 :e-とぴあ・かがわ BBスクエア
●  URL:http://gd...
Upcoming SlideShare
Loading in …5
×

Ginとbindataで作るシングルバイナリWebApp

3,306 views

Published on

第2回 関西golang勉強会
http://kug2.connpass.com/event/23647/

Published in: Technology
  • Be the first to comment

Ginとbindataで作るシングルバイナリWebApp

  1. 1. 堀内 晨彦 @hico_horiuchi Ginとbindataで作る シングルバイナリWebApp
  2. 2. 自己紹介 Akihiko Horiuchi 香川大学 修士2年 bit.ly/hiconyan 研究室のインフラと掃除担当 github.com/sai-lab/mouryou github.com/sai-lab/mouryou-web Emacs / Ruby / Rails / Golang Hubot / Sensu / Ansible 16/01/23 2
  3. 3. シェルスクリプトマガジン! ●  「香川大学SLPからお届け!」シリーズ ○  Vol. 33 Go言語とMithril.jsでWebアプリ開発 バックエンド編 ○  Vol. 34 Go言語とMithril.jsでWebアプリ開発 フロントエンド編 ○  (Amazonで著者セントラル作りたい…) 16/01/23 3
  4. 4. GoでWebAppを作るメリット ●  シングルバイナリ でデプロイ ○  コンパイルしたバイナリをアップロードするだけ ○  ライブラリのインストールなどが要らない ○  コンテナ や マイクロサービス との親和性が高そう ●  インタプリタと比較して 高速・軽量 ○  Railsより50倍の速度と10倍の省メモリという話も[1] ●  コーディング規約 を統一 ○  gofmt(goimports)で強制的に直される ○  可読性が上がる、チーム開発がスムーズになる 16/01/23 4 [1] https://plus.google.com/+MattAimonetti/posts/PeZk8FY3PWY
  5. 5. GoでWebAppを作るデメリット ●  Webフレームワーク 戦国時代 ○  シンプル < Gin < Goji < Martini < Revel < フルスタック ○  Railsのようなデファクトスタンダードが決まっていない ●  ORマッパーも 戦国時代[2] ○  シンプル < gorp < Genmai < GORM < フルスタック ●  アセット どうするの問題 ○  バイナリ + HTML + CSS + JavaScript ? ○  bindata でバイナリ化・ソースコード化できる ○  tdewolff/minify でMinifyができるらしい 16/01/23 5 [2] http://hachibeechan.hateblo.jp/entry/2015/03/25/Go言語でのORMを色々検討してみた
  6. 6. デモンストレーション 「kakuzuke」 http://kakuzuke.hiconyan.com/ https://github.com/hico-horiuchi/kakuzuke 16/01/23 6
  7. 7. デモンストレーション 「yosage」 http://yosage.hiconyan.com/ https://github.com/hico-horiuchi/yosage 16/01/23 7
  8. 8. オススメのパッケージ ●  github.com/gin-gonic/gin ○  構造体をJSONで返せるのでAPIサーバとして使う ●  github.com/yosssi/ace ○  Slimライクに html/template を書ける ●  github.com/jteeuwen/go-bindata ○  ファイルを []byte のソースコードに変換する ●  github.com/pilu/fresh ○  ソースコードの変更を検知してビルドと再起動をする ●  github.com/mattn/gom ○  Gemライクなパッケージ管理ツール 16/01/23 8
  9. 9. 僕が考えた最強のディレクトリ構成 16/01/23 9 webapp/ ├ app/ │ ├ controllers/ Mithril.jsのコントローラ │ ├ views/ Mithril.jsのビュー │ └ app.js Mithril.jsの本体 ├ assets/ │ ├ fonts/ Webフォント(eot、svg、woff) │ ├ images/ Faviconなど │ ├ javascripts/ mithril.min.jsなど │ └ stylesheets/ bootstrap.min.cssなど ├ lib/ │ ├ controllers/ Ginのコントローラ │ ├ models/ 構造体の定義 │ └ views/ Aceのテンプレート ├ Gomfile ├ Makefile └ router.go Ginのルーティングなど
  10. 10. 今回のポイント・工夫 ●  GinでMVCデザインのAPIサーバを作成 ○  これまでRails + Grapeで開発していたので ○  Viewはヘッダー・ナビゲーションバー・フッターのみ ●  フロントエンドはMithril.jsで作成 ○  MVCデザインのJavaScriptフレームワーク ○  仮想DOM 採用で、Reactよりも 高速・軽量 ○  モデルはAPIから返ってきたJSONをそのまま使う ○  ソースコードはバイナリ化してGinで配信 バックエンドはGoで最速のフレームワーク フロントエンドもJavaScriptで最軽量のフレームワーク 16/01/23 10
  11. 11. GinでAPIサーバを作成(1) ●  モデルを構造体で定義 ○  lib/models/user.go ○  `json:"login"` のようなタグ(アノテーション)を付ける 16/01/23 11 type User struct { Login *string `json:"login"` AvatarURL *string `json:"avatar_url"` CurrentStreak *int `json:"current_streak"` Me *bool `json:"me"` } type UserList []*User
  12. 12. GinでAPIサーバを作成(2) ●  コントローラでJSONを返却 ○  lib/controllers/ranking_controller.go ○  c.JSON で構造体をJSONとして返せる 16/01/23 12 type RankingController struct { controller } func (_ RankingController) ShowAPI(c *gin.Context) { username := c.Param("username") followees := GitHubClient.Users.ListFollowing(username) users := make([]*models.User, len(followees)) var list models.UserList = users sort.Sort(list) c.JSON(http.StatusOK, list) }
  13. 13. Aceでテンプレートを作成 ●  ヘッダーとナビゲーションバーのみ ○  lib/view/layout.ace 16/01/23 13 = doctype html html lang="en" head title kakuzuke link href="/assets/stylesheets/bootstrap.min.css" rel="stylesheet" body nav.navbar.navbar-fixed-top.bg-white .container a#app-title.navbar-brand.text-kakuzuke href="/" i.fa.fa-trophy.m-r-sm span.bold kakuzuke .container.m-y-md = yield main script src="/assets/javascripts/mithril.min.js" script src="/app/app.js" type="text/javascript"
  14. 14. bindataでアセットをバイナリ化 ●  app/ と assets/ と lib/views/ をバイナリ化 ○  Makefile で変換するようにした ○  go-bindata-assetfs を使うと http.FileSystem になる ○  -debug=true ではバイナリ化せずにファイルを開く ○  結果は package main な bindata_assetfs.go に吐き出される 16/01/23 14 bindata: gom exec go-bindata-assetfs ./app/... ./assets/... ./lib/views/... debugdata: gom exec go-bindata-assetfs -debug=true ./app/... ./assets/...
  15. 15. Ginでbindataを配信 ●  ここがちょっと面倒 ○  router.go ○  Ginでは http.FileServer ではなく static.Serve を使う ○  http.FileSystem も使えないので BinaryFileSystem を作る ○  gin-gonic/contrib/static/example/bindata/example.go 16/01/23 15 func main() { ranking := controllers.RankingController{} router := gin.Default() router.Use(static.Serve("/app", BinaryFileSystem("app"))) router.Use(static.Serve("/assets", BinaryFileSystem("assets"))) router.GET("/api/ranking/:username", ranking.ShowAPI) router.Run() }
  16. 16. freshでビルドしながら開発 ●  ソースコードの変更を検知してリビルド ○  変更の反映にコンパイルが必要なGoの強い味方 ○  JavaScriptだとGrantとかgulpみたいな感じ? ○  監視する拡張子と間隔を設定できる 16/01/23 16 $ gom exec fresh -c runner.conf Loading settings from runner.conf 22:7:30 runner | InitFolders 22:7:30 runner | mkdir ./tmp 22:7:30 runner | mkdir ./tmp: file exists 22:7:30 watcher | Watching . 22:7:30 watcher | Watching app 22:7:30 watcher | Watching app/controllers 22:7:30 watcher | Watching app/views
  17. 17. まとめ・おわりに ●  Ginとbindataで シングルバイナリ を実現 ○  kakuzukeだと最終的なバイナリが 8MB 程になる ○  bindata_assetfs.go で 2MB 、Minifyすれば軽量化できそう ●  GomからGodepに移行したい ○  Gomはシンプルだけどリビジョンを付けてくれない ○  Herokuで .godir は非推奨(Godep使えと言われる) ○  gin-gonic/contrib#75 みたいな時に面倒くさい ●  bindataを生成するタイミング ○  gitignore に追加すべきかどうか ○  複数人で開発するときにはルールが必要そう 16/01/23 17
  18. 18. Golang勉強会 in Kagawa 「Golang勉強会 in Kagawa」を開催します! ●  日時 :2016年2月27日(土) 13:00∼18:00 ●  場所 :e-とぴあ・かがわ BBスクエア ●  URL:http://gdgshikoku.connpass.com ○  前半はハンズオン、後半はセッションの予定 ○  登壇者は @tenntenn 、@taknb2nch 、@hico_horiuchi ○  発表者募集中です!詳細は @hico_horiuchi まで 16/01/23 18 with

×