Slide 1

Slide 1 text

How do you design Web API in Golang? Gopher Dojo#1, MAY 28 2018 Sho Ito Connehito Inc. @itosho

Slide 2

Slide 2 text

自己紹介 How do you design Web API in Golang? ● 伊藤 翔, @itosho ○ 所属: コネヒト株式会社 / Supership株式会社 ● 普段はバックエンドエンジニア ○ よく書く言語: PHP / Ruby ● 個人でいくつかサービスつくっています ○ https://itosho.github.io/ ● 野球とアイドルが好きです⚾

Slide 3

Slide 3 text

Gopher道場で学べてよかったこと How do you design Web API in Golang? ● CLIツールの基礎 ● Goにおけるユニットテストの考え方 ● 実践的なgoroutineの知識 ● contextパッケージの使い方 ● Goっぽい書き方 / Goの学び方

Slide 4

Slide 4 text

控えめに言って最高! ありがとうございました! 感想

Slide 5

Slide 5 text

もっと知りたい! 欲張りですいません! でも…

Slide 6

Slide 6 text

今日話すこと How do you design Web API in Golang? ● GoにおけるWeb API開発で3大よく分かっていないこと ○ 雰囲気で現状はこうしてるという話をします ● 懇親会等でみなさんの知見や意見を聞きたい ○ スライド公開するのでソーシャル上でも意見もらえると嬉しいです

Slide 7

Slide 7 text

前提 How do you design Web API in Golang? ● インディー開発 ● 規模は小さい ○ エンドポイント数:17 ○ テーブル数:10 ○ 単一リソースに対するCRUD処理がほとんど ● インフラはVPS ● データベースはMySQL

Slide 8

Slide 8 text

その1: ORMライブラリ

Slide 9

Slide 9 text

選択肢 How do you design Web API in Golang? ● GORM ● genmai ● 標準パッケージ(database/sql) ○ 他にも色々あるけど触ったことがあるのは上記3つ

Slide 10

Slide 10 text

現状 How do you design Web API in Golang? ● GORMを使っている ○ 初心者に database/sql はちょっと気が重い ○ Rails上がりなのでとっつきやすい ○ ドキュメントが充実している(情報もgenmaiより多い)

Slide 11

Slide 11 text

ここがよく分からない How do you design Web API in Golang? ● うまく言語化出来てないけど、あんまりGoっぽくない ○ 既にスキーマ管理は別でやってる ● 複雑なことをすると辛そう ● datetime型の扱いが面倒 ○ 参考: 「Golangのgormで、カスタマイズしたtime.Timeに差し変える」 ■ https://qiita.com/roothybrid7/items/52623bedb45ff0c26a8a ● genmaiのほうがバランスいいかも? ○ ただ、genmaiはタグの使い方が他と違うような気がする ● 最終的には database/sql or GAE/Datastore?

Slide 12

Slide 12 text

その2: パッケージ構成

Slide 13

Slide 13 text

現状 How do you design Web API in Golang? MVCライクな構成 server: →Railsで言うコントローラ model: →構造体定義, 1テーブル1ファイル database: →db接続(後述) / スキーマ管理 assets: →静的ファイルを格納 main.go: →ルーティングとHTTPハンドラ定義 ※go-json-restを利用

Slide 14

Slide 14 text

database/database.go How do you design Web API in Golang? var DB *gorm.DB // main.goでInitDBを呼び出す // database.DB.First(&user, id).Error のような形で利用 func InitDB() { var err error user := os.Getenv("MYSQL_USER") pass := os.Getenv("MYSQL_PASSWORD") parameter := "charset=utf8&parseTime=True&loc=Asia%2FTokyo" DB, err = gorm.Open("mysql", user+":"+pass+"@/hoge?"+parameter) // 省略 }

Slide 15

Slide 15 text

ここがよく分からない How do you design Web API in Golang? ● database接続変数がグローバル変数なのはしょうがない? ● 今後server / modelパッケージが肥大化していった時はどうすれば? ○ ググるとDDDライクな例をよくみるけど…? ■ 自分のサービスだと若干オーバースペックに感じる

Slide 16

Slide 16 text

その3: インフラ環境

Slide 17

Slide 17 text

現状 How do you design Web API in Golang? Nginx MySQL Golang Supervisor client ● nginxを前段に置いている ● Supervisorを利用して、デーモン化している ● 静的ファイルは http.FileServer を利用して配信 ● デプロイはバイナリをアップロードするだけ static files

Slide 18

Slide 18 text

main.go How do you design Web API in Golang? func main() { // 省略 l, err := net.Listen("tcp", ":8080") if err != nil { return } http.Handle("/v1/", http.StripPrefix("/v1", api.MakeHandler())) http.Handle("/assets/", http.StripPrefix("/assets", http.FileServer(http.Dir("./assets")))) fcgi.Serve(l, nil) }

Slide 19

Slide 19 text

ここがよく分からない How do you design Web API in Golang? ● 静的ファイルの配信方法 ○ ぶっちゃけS3を利用したほうが楽そう ● デーモン化はSupervisorを利用する以外に便利な方法があるのか? ● nginx + goのベストプラクティス ○ 参考: 「Nginx with Goのパフォーマンスを検証した」 ■ http://tsuyoshi-nakamura.hatenablog.com/entry/2016/12/25/182946 ● GAEにすればORM含めて色々解決する説

Slide 20

Slide 20 text

みなさんの意見を聞かせてください! まとめ

Slide 21

Slide 21 text

ご清聴ありがとうございました