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

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

Sponsored · SiteGround - Reliable hosting with speed, security, and support you can count on.

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

Avatar for Ryosuke Nishigami

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