Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
長年運用されている Web サービスと 通信をするクライアントを Go で作ってみた話
Search
こもじゅん
December 04, 2023
Programming
0
670
長年運用されている Web サービスと 通信をするクライアントを Go で作ってみた話
カヤック・アンドパッド 合同 プロポーザル供養会 での発表
https://connpass.com/event/301666/
こもじゅん
December 04, 2023
Tweet
Share
More Decks by こもじゅん
See All by こもじゅん
XWalkViewを利用したクロスプラットフォームアプリの開発
commojun
0
900
Other Decks in Programming
See All in Programming
CSC307 Lecture 06
javiergs
PRO
0
360
Mastering Developer Experience: A Roadmap for Success 【開発生産性Conference 2024】
findyinc
1
380
Activities at Cairo Library
cairolibrary720
0
1.2k
【Go言語】ジェネリクス
tomo1227
0
170
[After Kotlin Fest 2024 LT Night @ Sansan] もっともっとKotlinを好きになる!K2 Compiler Pluginで遊んでみよう!
kitakkun
2
260
Async Await: Mastering Python's Time-Bending Tricks - EuroPython2024
yanbo
1
290
Xcode 16のPreviewModifierと@Previewableを活用した効率的なプレビュー方法の考察
ojun9
2
160
유연한 Composable 설계
l2hyunwoo
0
380
Clean Architecture by TypeScript & NestJS
ryounasso
0
150
しくじり先生 Image Matching Challenge 2024 編
goosehaaan
0
810
生成AIをkintoneに連携してみた
hideg
0
230
大規模マルチテナントを解決するYugabyteDBという選択肢
nnaka2992
1
250
Featured
See All Featured
Dealing with People You Can't Stand - Big Design 2015
cassininazir
360
22k
The Power of CSS Pseudo Elements
geoffreycrofte
64
5.2k
The Cult of Friendly URLs
andyhume
75
5.9k
Build your cross-platform service in a week with App Engine
jlugia
227
17k
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
16
1.6k
Visualization
eitanlees
139
14k
実際に使うSQLの書き方 徹底解説 / pgcon21j-tutorial
soudai
149
45k
A designer walks into a library…
pauljervisheath
201
24k
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
13
430
Designing for humans not robots
tammielis
247
25k
Exploring the Power of Turbo Streams & Action Cable | RailsConf2023
kevinliebholz
12
3.8k
Imperfection Machines: The Place of Print at Facebook
scottboms
262
13k
Transcript
長年運用されている Web サービスと 通信をするクライアントを Go で作ってみた話 commojun (株式会社カヤック)
自己紹介 commojun (大澤 純) 2016年新卒入社 サーバサイドエンジニア ぼくらの甲子園!ポケットというソーシャルゲームの運用に従事 趣味 - 🎺
- 異世界転生アニメ - 最近娘が1歳になった
今日の内容 https://fortee.jp/yapc-hiroshima-2024/proposal/d2140bb9-c915-46cc-a05d-24532a190263
ちなみにEC2からECSに移行をやったこともあります 今日はSREの発表が多いので… https://yapcjapan.org/2022online/timetable.html#talk-21
本題へ
甲子園ポケットとは 高校球児をロールプレイする野球ゲーム 15人vs15人のユーザで野球をするGvG 2014年リリース、今年で9周年
このプロジェクトに長らく従事しています 甲子園ポケットのサーバはPerlでできています
カヤックはGoに力を入れます宣言 https://www.kayac.com/news/2014/08/golang ※
このままだと僕のキャリアの行方は…? 2010年代前半のものづくりの延長線でしかキャリアを積めていない このままで大丈夫か?という疑問が ※ 開発部署によってこれ以外の言語も多様に選ばれています
Perlエンジニアの年収が高い? https://ledge.ai/articles/persol-hr-forecaster-map
Perlエンジニアの年収が高い? https://ledge.ai/articles/persol-hr-forecaster-map ledge.aiの記事より引用 > いま平均年収が高い言語は、以前からニーズが高く、経験や知識が豊富なエン ジニアが多いため、学びたい言語と年収の高い言語の順位に乖離が生じたと考え られる。 (※学びたい言語 ≒ 現在人気の言語)
優秀なPerl技術者は、Perlだけにとどまらず、 時代によるトレンドの変貌の波にうまく乗って力強く生きている
やはり新しいことに挑戦すべき 自分の社内ニーズを上げるため 今後のキャリアのため Goでなにか1からシステムを書いてみよう その事実を作っておけば、チャンスが来たときに声がかかりやすい
考えた題材:ゲームを勝手にプレイするAI • サーバに対してAPI通信を行うクライアントをGo で書く • Unity製のクライアントアプリと同等のことができ る • ただし、何をするかを人間が考えるのではなく、 AIが自律的に判断して行動する
Goでなにかを作ってみる題材としてはかなり多くのこ とが学べそう
AIの話はありません! AIと言いましたが… ◯ Perl製の既存プロジェクトに対してクライアントがAPI通信 できるようになるまでに苦しんだこと ✕ AIの内容、作り方、効果 AIの中身について考えられるほ ど制作は進捗していません
API通信をするにあたって必要なこと サーバとデータをJSONでやり取りする Goは静的型付け言語なので、JSONに含まれる要 素と型情報を構造体に列挙しなければならない JSON <-> Go構造体変換をしつつ、httpリクエスト を組み立てたり、レスポンスを解釈するコードをす べてのAPIに対して書く必要がある
なにか良いツールはないか? • 自分はGo初心者なので、既にあるツールをうまく使って車輪の再発明を避けたい • サーバ - クライアント間でJSONをやりとりしてくれるコードをいちいち書くのが面倒 という悩みはみんな持つはずだ! • そういったコードを自動生成してくれるツールが絶対世の中にあるはず
• みんなが使うツールに乗っかってこそ、初心者を脱出できるはずなんだ!
None
OpenAPIとは • 元はSwaggerと呼ばれていた • REST APIの仕様を記述するためのとても有名な フォーマット • yml形式でAPI仕様書を書く •
API仕様書にリクエストとレスポンスの要素・型情報を 書けば、(Goも含め)様々な言語のコードを生成 してくれる • webUI上で編集したり、モックサーバを作成できたり 多機能 とても名のあるツールなので、使えるようになっておこう!
生成したコードを使うと… リクエストをJSONに変換する部 分や、レスポンスで受け取った JSONを解釈する部分を意識せ ずに、API通信を行うというコー ドを書くことができる
壁に当たる とりあえず手作業でymlをいくつか書いてみたが… 9年運用しているサーバはリクエスト/レスポンスの型情報が複雑 例えば… 要素数1万超え、ネスト深さ5以上のJSON 手作業でAPI定義のymlを書くのは難しい そもそも既存のAPI定義書は無いのか? -> ある
API定義書: Baal 甲子園ポケットにもAPI定義書はある 弊社独自のAPI定義書のフォーマット これを使ってクライアントアプリ( Unity C#)のコード生成 をしている サーバのコード生成はしていない これを使ってOpenAPIのymlを生成してみよう
(API定義書の変換) https://techblog.kayac.com/unity_advent_calendar_2016_20
openapi.yml API定義 Goの 通信関連 コード openapi-generator Baal API定義 yaml-generator これを作ってみよう
Go製Baalパーサー
テンプレートエンジンを使ってymlを生成 Baalパーサーとテンプレートエンジンの 使い方の習得に苦戦 苦労して出来上がったymlのテンプレート→ 呪いの呪文のようだ
これでAPI通信基盤が完成!
とはならなかった! ダメです
API通信失敗 BaalによるAPI定義書 -> OpenAPIのAPI定義書 -> コード生成 によって生成したコードで通信を投げてみたが、 「型情報が違うのでJSONを解釈できない」というエラーが… API定義書に従ってコード生成したのに…?
サーバが返すJSONが型に厳密ではなかった • 文字列として扱いたいのに、数値として送信してくる 場合がある • 数値として扱いたいのに、文字列として送信してくる 場合がある • 正しく送信してくる場合もある →文字/数値の扱いが不定のJSONを柔軟に
受け取れるようにする必要がある (サーバを直すというのは今回自身に課したレギュレーション的にナシ)
型を柔軟に受け取るには、JSON解析後の型当てはめを自分 で実装する必要がある Response JSON Go 構造体 型付き JSON解析&型当てはめ Response JSON
Go 構造体 なんでも型 JSON解析 Go 構造体 型付き 型当てはめ この処理を今回のケースに合わせて自作する必要がある
OpenAPI、ダメかも openapi.yml API定義 Goの 通信関連 コード openapi-generator Baal API定義 yaml-generator
Response JSON Go 構造体 型付き JSON解析&型当てはめ OpanAPIが生成したコードがブラックボッ クスで、生成物をカスタマイズできなかっ た Goであるがゆえに難しい
OpenAPIを使うのをやめる
そもそもなぜOpenAPIを使ったか? Goの構造体と通信を担うコードを生成するのは難しいと感じたから 既存の仕組みにはなるべく乗っかるべきだと思っていたから openapi.yml API定義 Goの 通信関連 コード openapi-generator Baal
API定義 yaml-generator Baal API定義 Goの 通信関連 コード client-generator (自作) ここを自前で作るのは難しい(と思っていた) これを辞めて これをやることにした ツールを辞めて自前で作ることで、 JSONの型について 柔軟なしくみを作れるようになる
実は、知らない間に実力がついていた openapi.yml API定義 Goの 通信関連 コード openapi-generator Baal API定義 yaml-generator
Baal API定義 Goの 通信関連 コード client-generator (自作) これを作るのに必要な要素 - Baalパーサを扱うこと - テンプレートエンジンを扱うこと これを作るのに必要な要素 - Baalパーサを扱うこと - テンプレートエンジンを扱うこと 難しいと思っていたことが もうできるようになっていた
コード生成を自前で作ることにした • 結果として、Baal API定義書からコード生成するジェネレータを自前で 書けるようになった。 • API通信の土台がやっと完成した AI開発のスタート地点に
教訓 • 初心者意識はいつまでも持つものじゃない • Goは既存のコードをカスタマイズするのが難しい • 既存のツールの恩恵にあやかろうとしすぎず、 自分に必要な物だけを自前で用意する方が良い時もある • がっつり失敗したほうが身につく物もある
なぜこんなことをしたのか • 今現在の仕事で得られる経験がなくなってしまった -> 異動の希望? -> 転職? -> それ以外にもやりようはあるのではないか •
数年かけて仕事を覚え、効率化し、余白を作った 余白を使い、今のプロジェクトのまま新しい経験が得られる題材を自分で 設定した
None