Slide 1

Slide 1 text

Copyright (C) GENDA Inc. All Rights Reserved. コード生成を利用した 新規プロジェクトの成功と失敗 株式会社GENDA 西上良祐 - 2022.12.13

Slide 2

Slide 2 text

Copyright (C) GENDA Inc. All Rights Reserved. ・ ゲームセンターのDXプロジェクトで店舗スタッフ向けの社内ツールを開発 ・ その社内ツールのGo API実装時に得られたコード生成の成功事例と失敗事例を お伝えします 2 本日お伝えすること

Slide 3

Slide 3 text

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

Slide 4

Slide 4 text

Copyright (C) GENDA Inc. All Rights Reserved. 株式会社GENDA テックリード Go / React.js 趣味 - オンライン麻雀 - ボドゲ - モダンアート - アヴァロン - etc. 4 にしがみりょうすけ 西上 良祐 @_nishisuke 自己紹介

Slide 5

Slide 5 text

Copyright (C) GENDA Inc. All Rights Reserved. 社名 代表取締役社長 設立 資本金 株式会社GENDA 申 真衣 2018年5月 23億3,228万円(資本準備金等含む) 従業員数 連結:約4,000名(パート・アルバイト含む/2022年1月末日現在) 所在地 東京都港区東新橋1-9-1 東京汐留ビルディング17F 5 GENDA概要

Slide 6

Slide 6 text

Copyright (C) GENDA Inc. All Rights Reserved. 6 世界中の人々の人生を より楽しく ASPIRATION

Slide 7

Slide 7 text

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グループ企業

Slide 8

Slide 8 text

Copyright (C) GENDA Inc. All Rights Reserved. 日本全国(約250店舗)および海外にてアミューズメント施設を運営(2022/11/15現在) 世界的な日本アニメブームを背景に、クレーンゲーム需要が急速に拡大中 8 アミューズメント施設運営

Slide 9

Slide 9 text

Copyright (C) GENDA Inc. All Rights Reserved. アミューズメント施設でしか遊べなかったクレーンゲームを インターネットを通じて遠隔操作し、いつでもどこでも遊べることが価値となっているサービス コロナ禍によって成長が加速化している事業 オタクレ 2022/03 サービス開始 その他のオンラインクレーンゲームサービス 9 オンラインクレーンゲーム

Slide 10

Slide 10 text

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

Slide 11

Slide 11 text

Copyright (C) GENDA Inc. All Rights Reserved. 11 システム構成と担当チーム

Slide 12

Slide 12 text

Copyright (C) GENDA Inc. All Rights Reserved. 12 システム構成と担当チーム

Slide 13

Slide 13 text

Copyright (C) GENDA Inc. All Rights Reserved. ・ REST API ・ JSONを受け取りJSONを返す ・ クリーンアーキテクチャ 13 Go APIの概要

Slide 14

Slide 14 text

Copyright (C) GENDA Inc. All Rights Reserved. ・ 今回のAPI実装に伴いコードを生成させた ・ そこで得られた成功事例と失敗事例を紹介 14 コード生成の成功と失敗

Slide 15

Slide 15 text

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

Slide 16

Slide 16 text

Copyright (C) GENDA Inc. All Rights Reserved. 16 Request/Responce BodyのGoの構造体

Slide 17

Slide 17 text

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の構造体

Slide 18

Slide 18 text

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

Slide 19

Slide 19 text

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

Slide 20

Slide 20 text

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

Slide 21

Slide 21 text

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の初期化部分 成功事例

Slide 22

Slide 22 text

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

Slide 23

Slide 23 text

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

Slide 24

Slide 24 text

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

Slide 25

Slide 25 text

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

Slide 26

Slide 26 text

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

Slide 27

Slide 27 text

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 インターフェイスのモック実装 成功事例

Slide 28

Slide 28 text

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

Slide 29

Slide 29 text

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" } テストテンプレートを生成 (生成物は次ページ)

Slide 30

Slide 30 text

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 テストのテンプレート

Slide 31

Slide 31 text

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 テストのテンプレート 成功事例

Slide 32

Slide 32 text

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

Slide 33

Slide 33 text

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