Upgrade to Pro — share decks privately, control downloads, hide ads and more …

コード生成を利用した新規プロジェクトの成功と失敗

 コード生成を利用した新規プロジェクトの成功と失敗

Ryosuke Nishigami

December 13, 2022
Tweet

Other Decks in Technology

Transcript

  1. Copyright (C) GENDA Inc. All Rights Reserved. ・ ゲームセンターのDXプロジェクトで店舗スタッフ向けの社内ツールを開発 ・

    その社内ツールのGo API実装時に得られたコード生成の成功事例と失敗事例を お伝えします 2 本日お伝えすること
  2. Copyright (C) GENDA Inc. All Rights Reserved. ・ 自己紹介 ・

    株式会社GENDAの概要 ・ ゲームセンターDXの概要 ・ コード生成の成功と失敗 ・ まとめ 3 目次
  3. Copyright (C) GENDA Inc. All Rights Reserved. 株式会社GENDA テックリード Go

    / React.js 趣味 - オンライン麻雀 - ボドゲ - モダンアート - アヴァロン - etc. 4 にしがみりょうすけ 西上 良祐 @_nishisuke 自己紹介
  4. Copyright (C) GENDA Inc. All Rights Reserved. 社名 代表取締役社長 設立

    資本金 株式会社GENDA 申 真衣 2018年5月 23億3,228万円(資本準備金等含む) 従業員数 連結:約4,000名(パート・アルバイト含む/2022年1月末日現在) 所在地 東京都港区東新橋1-9-1 東京汐留ビルディング17F 5 GENDA概要
  5. Copyright (C) GENDA Inc. All Rights Reserved. アミューズメント施設運営事業 オンラインクレーンゲーム事業 (持株比率:100%)

    株式会社GENDA GiGO Entertainment キャラクターライセンス事業 (持株比率:51%) 株式会社トーキョー キャラクター メーカーズ セールスプロモーション事業 (持株比率:100%) 株式会社エスピーエスエス 中国事業 (持株比率:79.5%) 伍彩汇业(广州)贸易有限公司 株式会社GENDA Games アミューズメントマシンレンタル事業 オンラインクレーンゲーム事業 (持株比率:100%) 株式会社GENDA 持株会社 米国事業 (持分法適用会社 持株比率:50%) Kiddleton, Inc. 株式会社ダイナモアミューズメント VRコンテンツ事業 (持分法適用会社 持株比率:20.8%) 7 GENDAグループ企業
  6. Copyright (C) GENDA Inc. All Rights Reserved. ・ GENDAの主要な事業の1つである、株式会社GENDA GiGO

    Entertainment(以下 GGE)のアミューズメント施設運営事業のDX化 ・ ゲームセンター運営の課題 ◦ 紙を印刷し、それに加筆し作業指示をする ◦ 景品情報の参照や売上のチェックが事務室のPCでしかできない ▪ クレーンとの往復が必要 ・ 店舗の作業を効率化する店舗スタッフ用ツール「GiGO Navigation Apps」を開 発 10 ゲームセンターDXの概要
  7. Copyright (C) GENDA Inc. All Rights Reserved. ・ REST API

    ・ JSONを受け取りJSONを返す ・ クリーンアーキテクチャ 13 Go APIの概要
  8. Copyright (C) GENDA Inc. All Rights Reserved. ・ 今回のAPI実装に伴いコードを生成させた ・

    そこで得られた成功事例と失敗事例を紹介 14 コード生成の成功と失敗
  9. Copyright (C) GENDA Inc. All Rights Reserved. ・ Request/Response BodyのGoの構造体

    ・ DIの初期化部分 ・ DBテーブルに対応するGoの構造体 ・ インターフェイスのモック実装 ・ テストのテンプレート 15 APIを実装するにあたりコード生成したもの
  10. Copyright (C) GENDA Inc. All Rights Reserved. ツール  https://github.com/OpenAPITools/openapi-generator コマンド

    生成されたGoコード抜粋 17 docker run -v "${PWD}:/local" openapitools/openapi-generator-cli generate \ -i ./path/to/openapi.yaml -g go \ -o /output/dir --package-name packagename; type PostUserRequest struct { Name *string `json:"name,omitempty"` } Request/Responce BodyのGoの構造体
  11. Copyright (C) GENDA Inc. All Rights Reserved. 18 ・ 課題となったこと

    ◦ 業務委託メインで開発していたため、バリデーションに広く普及しているライブラリを採用し たくなった ▪ https://github.com/go-playground/validator ・ 結果 ◦ 生成した構造体を編集するのは現実的でなかった ◦ APIの実装からOpenAPI.ymlを生成すべきだった Request/Responce BodyのGoの構造体 失敗事例
  12. Copyright (C) GENDA Inc. All Rights Reserved. ・ Request/Response BodyのGoの構造体

    ・ DIの初期化部分 ・ DBテーブルに対応するGoの構造体 ・ インターフェイスのモック実装 ・ テストのテンプレート 19 APIを実装するにあたりコード生成したもの
  13. Copyright (C) GENDA Inc. All Rights Reserved. ツール  https://github.com/google/wire コマンド

    20 // 簡易的なDIのコード type Bar struct { fooer Fooer } type Fooer interface { Foo() string } type MyFooer struct {} func (b MyFooer) Foo() string { return "Hello foo" } // WireのOutput func NewBar() Bar { myFooer := &MyFooer{} bar := Bar{ fooer: myFooer, } return bar } DIの初期化部分 wire
  14. Copyright (C) GENDA Inc. All Rights Reserved. // main.go type

    Fooer interface { Foo() string } type MyFooer struct {} func (b MyFooer) Foo() string { return "Hello foo" } func provideMyFooer() MyFooer { return MyFooer{} } type Bar struct { fooer Fooer } // wire.go var Set = wire.NewSet( wire.Struct(new(MyFooer), "*"), wire.Bind(new(Fooer), new(*MyFooer)), wire.Struct(new(Bar), "*")) func NewBar() Bar { wire.Build(Set) return Bar{} } 21 DIの初期化部分 成功事例
  15. Copyright (C) GENDA Inc. All Rights Reserved. ・ Request/Response BodyのGoの構造体

    ・ DIの初期化部分 ・ DBテーブルに対応するGoの構造体 ・ インターフェイスのモック実装 ・ テストのテンプレート 22 APIを実装するにあたりコード生成したもの
  16. Copyright (C) GENDA Inc. All Rights Reserved. ツール  https://github.com/xo/xo コマンド

    DB ➡ Goの構造体 // 生成された構造体 type User struct { ID uint64 `json:"id"` Age uint64 `json:"age"` Name string `json:"name"` } 23 usersテーブル id SERIAL age SMALLINT UNSIGNED name VARCHAR(50) DBテーブルに対応するGoの構造体 xo schema mysql://u:p@host:3306/db -o path/to/output
  17. Copyright (C) GENDA Inc. All Rights Reserved. ・ 行ったこと ◦

    「テーブル設計 ➡ 構造体を生成」を行い、実装コストを下げようとした ・ 結果 ◦ 最初期は楽だった ◦ リレーションの設定がデフォルトだとできない ▪ 初回の生成物だけコミット、その後は人間が編集するのが正解だった 24 DBテーブルに対応するGoの構造体 成功事例 かつ 失敗事例
  18. Copyright (C) GENDA Inc. All Rights Reserved. ・ Request/Response BodyのGoの構造体

    ・ DIの初期化部分 ・ DBテーブルに対応するGoの構造体 ・ インターフェイスのモック実装 ・ テストのテンプレート 25 APIを実装するにあたりコード生成したもの
  19. Copyright (C) GENDA Inc. All Rights Reserved. ツール  https://github.com/sanposhiho/gomockhandler コマンド

    // main.go type Fooer interface { Foo() string } モックを生成 (生成物は次ページ) 26 インターフェイスのモック実装 gomockhandler -source=main.go -destination=m.go
  20. Copyright (C) GENDA Inc. All Rights Reserved. // Output type

    MockFooer struct { ctrl *gomock.Controller recorder *MockFooerMockRecorder } func NewMockFooer(ctrl *gomock.Controller) *MockFooer { // Snip } func (m *MockFooer) Foo() string { // Snip } // 使い方 ctrl := gomock.NewController(t) mockFooer := NewMockFooer(ctrl) mockFooer.EXPECT().Foo() .Return("Hey") 27 インターフェイスのモック実装 成功事例
  21. Copyright (C) GENDA Inc. All Rights Reserved. ・ Request/Response BodyのGoの構造体

    ・ DIの初期化部分 ・ DBテーブルに対応するGoの構造体 ・ インターフェイスのモック実装 ・ テストのテンプレート 28 APIを実装するにあたりコード生成したもの
  22. Copyright (C) GENDA Inc. All Rights Reserved. ツール  https://github.com/cweill/gotests コマンド

    29 テストのテンプレート gotests -all main.go // main.go type MyFooer struct {} func (b MyFooer) Foo() string { return "Hello foo" } テストテンプレートを生成 (生成物は次ページ)
  23. Copyright (C) GENDA Inc. All Rights Reserved. func TestMyFooer_Foo(t *testing.T)

    { tests := []struct { name string b MyFooer want string }{ // TODO: Add test cases. } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { b := MyFooer{} if got := b.Foo(); got != tt.want { t.Errorf("MyFooer.Foo() = %v, want %v", got, tt.want) } }) } } 30 テストのテンプレート
  24. Copyright (C) GENDA Inc. All Rights Reserved. func TestMyFooer_Foo(t *testing.T)

    { tests := []struct { name string b MyFooer want string }{ {"case1", MyFooer{}, "Hey"}, {"case2", MyFooer{}, "Foo"} } for _, tt := range tests { // Snip } } 31 テストのテンプレート 成功事例
  25. Copyright (C) GENDA Inc. All Rights Reserved. 32 ・ 生成対象がシンプルかどうかで生成するか決める

    ・ 初回だけ生成するか、開発方法としてコード生成を採用するかは検討の余地が ある ・ テンプレートコードの生成は、失敗にはなりづらい まとめ
  26. Copyright (C) GENDA Inc. All Rights Reserved. GENDA Creators Blog

    募集要項/採用情報 We are hiring! 世界一のエンターテイメント企業に向けて、 エンジニアを絶賛募集中です エンターテイメントやDXに興味がある方、お待ちしています 33