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
830
長年運用されている Web サービスと 通信をするクライアントを Go で作ってみた話
カヤック・アンドパッド 合同 プロポーザル供養会 での発表
https://connpass.com/event/301666/
こもじゅん
December 04, 2023
Tweet
Share
More Decks by こもじゅん
See All by こもじゅん
甲子園ポケットの思い出を残そう
commojun
0
15
7年間運用したソーシャルゲームをAmazon EC2構成からAmazon ECS構成へと乗り換えた話
commojun
0
26
XWalkViewを利用したクロスプラットフォームアプリの開発
commojun
0
910
Other Decks in Programming
See All in Programming
もう少しテストを書きたいんじゃ〜 #phpstudy
o0h
PRO
19
4.1k
Jasprが凄い話
hyshu
0
180
ファインディLT_ポケモン対戦の定量的分析
fufufukakaka
0
940
データの整合性を保つ非同期処理アーキテクチャパターン / Async Architecture Patterns
mokuo
55
19k
推しメソッドsource_locationのしくみを探る - はじめてRubyのコードを読んでみた
nobu09
2
340
Honoのおもしろいミドルウェアをみてみよう
yusukebe
1
230
Formの複雑さに立ち向かう
bmthd
1
940
CloudNativePGを布教したい
nnaka2992
0
120
LINE messaging APIを使ってGoogleカレンダーと連携した予約ツールを作ってみた
takumakoike
0
120
第3回関東Kaggler会_AtCoderはKaggleの役に立つ
chettub
3
1.2k
PHPのバージョンアップ時にも役立ったAST
matsuo_atsushi
0
230
Kotlinの開発でも AIをいい感じに使いたい / Making the Most of AI in Kotlin Development
kohii00
5
1.4k
Featured
See All Featured
Let's Do A Bunch of Simple Stuff to Make Websites Faster
chriscoyier
507
140k
jQuery: Nuts, Bolts and Bling
dougneiner
63
7.7k
Statistics for Hackers
jakevdp
797
220k
Cheating the UX When There Is Nothing More to Optimize - PixelPioneers
stephaniewalter
280
13k
Put a Button on it: Removing Barriers to Going Fast.
kastner
60
3.7k
Building Applications with DynamoDB
mza
93
6.2k
Build your cross-platform service in a week with App Engine
jlugia
229
18k
Distributed Sagas: A Protocol for Coordinating Microservices
caitiem20
330
21k
The Psychology of Web Performance [Beyond Tellerrand 2023]
tammyeverts
46
2.3k
Chrome DevTools: State of the Union 2024 - Debugging React & Beyond
addyosmani
4
380
Designing Dashboards & Data Visualisations in Web Apps
destraynor
231
53k
What’s in a name? Adding method to the madness
productmarketing
PRO
22
3.3k
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