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

長年運用されている Web サービスと 通信をするクライアントを Go で作ってみた話

長年運用されている Web サービスと 通信をするクライアントを Go で作ってみた話

カヤック・アンドパッド 合同 プロポーザル供養会 での発表

https://connpass.com/event/301666/

こもじゅん

December 04, 2023
Tweet

More Decks by こもじゅん

Other Decks in Programming

Transcript

  1. 長年運用されている Web サービスと
    通信をするクライアントを
    Go で作ってみた話
    commojun
    (株式会社カヤック)

    View full-size slide

  2. 自己紹介
    commojun (大澤 純)
    2016年新卒入社
    サーバサイドエンジニア
    ぼくらの甲子園!ポケットというソーシャルゲームの運用に従事
    趣味
    - 🎺
    - 異世界転生アニメ
    - 最近娘が1歳になった

    View full-size slide

  3. 今日の内容
    https://fortee.jp/yapc-hiroshima-2024/proposal/d2140bb9-c915-46cc-a05d-24532a190263

    View full-size slide

  4. ちなみにEC2からECSに移行をやったこともあります
    今日はSREの発表が多いので…
    https://yapcjapan.org/2022online/timetable.html#talk-21

    View full-size slide

  5. 甲子園ポケットとは
    高校球児をロールプレイする野球ゲーム
    15人vs15人のユーザで野球をするGvG
    2014年リリース、今年で9周年

    View full-size slide

  6. このプロジェクトに長らく従事しています
    甲子園ポケットのサーバはPerlでできています

    View full-size slide

  7. カヤックはGoに力を入れます宣言
    https://www.kayac.com/news/2014/08/golang

    View full-size slide

  8. このままだと僕のキャリアの行方は…?
    2010年代前半のものづくりの延長線でしかキャリアを積めていない
    このままで大丈夫か?という疑問が
    ※ 開発部署によってこれ以外の言語も多様に選ばれています

    View full-size slide

  9. Perlエンジニアの年収が高い?
    https://ledge.ai/articles/persol-hr-forecaster-map

    View full-size slide

  10. Perlエンジニアの年収が高い?
    https://ledge.ai/articles/persol-hr-forecaster-map
    ledge.aiの記事より引用
    > いま平均年収が高い言語は、以前からニーズが高く、経験や知識が豊富なエン
    ジニアが多いため、学びたい言語と年収の高い言語の順位に乖離が生じたと考え
    られる。
    (※学びたい言語 ≒ 現在人気の言語)

    View full-size slide

  11. 優秀なPerl技術者は、Perlだけにとどまらず、
    時代によるトレンドの変貌の波にうまく乗って力強く生きている

    View full-size slide

  12. やはり新しいことに挑戦すべき
    自分の社内ニーズを上げるため
    今後のキャリアのため
    Goでなにか1からシステムを書いてみよう
    その事実を作っておけば、チャンスが来たときに声がかかりやすい

    View full-size slide

  13. 考えた題材:ゲームを勝手にプレイするAI
    ● サーバに対してAPI通信を行うクライアントをGo
    で書く
    ● Unity製のクライアントアプリと同等のことができ

    ● ただし、何をするかを人間が考えるのではなく、
    AIが自律的に判断して行動する
    Goでなにかを作ってみる題材としてはかなり多くのこ
    とが学べそう

    View full-size slide

  14. AIの話はありません!
    AIと言いましたが…
    ◯ Perl製の既存プロジェクトに対してクライアントがAPI通信
      できるようになるまでに苦しんだこと
    ✕ AIの内容、作り方、効果
    AIの中身について考えられるほ
    ど制作は進捗していません

    View full-size slide

  15. API通信をするにあたって必要なこと
    サーバとデータをJSONでやり取りする
    Goは静的型付け言語なので、JSONに含まれる要
    素と型情報を構造体に列挙しなければならない
    JSON <-> Go構造体変換をしつつ、httpリクエスト
    を組み立てたり、レスポンスを解釈するコードをす
    べてのAPIに対して書く必要がある

    View full-size slide

  16. なにか良いツールはないか?
    ● 自分はGo初心者なので、既にあるツールをうまく使って車輪の再発明を避けたい
    ● サーバ - クライアント間でJSONをやりとりしてくれるコードをいちいち書くのが面倒
    という悩みはみんな持つはずだ!
    ● そういったコードを自動生成してくれるツールが絶対世の中にあるはず
    ● みんなが使うツールに乗っかってこそ、初心者を脱出できるはずなんだ!

    View full-size slide

  17. OpenAPIとは
    ● 元はSwaggerと呼ばれていた
    ● REST APIの仕様を記述するためのとても有名な
    フォーマット
    ● yml形式でAPI仕様書を書く
    ● API仕様書にリクエストとレスポンスの要素・型情報を
    書けば、(Goも含め)様々な言語のコードを生成
    してくれる
    ● webUI上で編集したり、モックサーバを作成できたり
    多機能
    とても名のあるツールなので、使えるようになっておこう!

    View full-size slide

  18. 生成したコードを使うと…
    リクエストをJSONに変換する部
    分や、レスポンスで受け取った
    JSONを解釈する部分を意識せ
    ずに、API通信を行うというコー
    ドを書くことができる

    View full-size slide

  19. 壁に当たる
    とりあえず手作業でymlをいくつか書いてみたが…
    9年運用しているサーバはリクエスト/レスポンスの型情報が複雑
    例えば…
    要素数1万超え、ネスト深さ5以上のJSON
    手作業でAPI定義のymlを書くのは難しい
    そもそも既存のAPI定義書は無いのか? -> ある

    View full-size slide

  20. API定義書: Baal
    甲子園ポケットにもAPI定義書はある
    弊社独自のAPI定義書のフォーマット
    これを使ってクライアントアプリ(
    Unity C#)のコード生成
    をしている
    サーバのコード生成はしていない
    これを使ってOpenAPIのymlを生成してみよう
    (API定義書の変換)
    https://techblog.kayac.com/unity_advent_calendar_2016_20

    View full-size slide

  21. openapi.yml
    API定義
    Goの
    通信関連
    コード
    openapi-generator
    Baal
    API定義
    yaml-generator
    これを作ってみよう

    View full-size slide

  22. Go製Baalパーサー

    View full-size slide

  23. テンプレートエンジンを使ってymlを生成
    Baalパーサーとテンプレートエンジンの
    使い方の習得に苦戦
    苦労して出来上がったymlのテンプレート→
    呪いの呪文のようだ

    View full-size slide

  24. これでAPI通信基盤が完成!

    View full-size slide

  25. とはならなかった!
    ダメです

    View full-size slide

  26. API通信失敗
    BaalによるAPI定義書 -> OpenAPIのAPI定義書 -> コード生成
    によって生成したコードで通信を投げてみたが、
    「型情報が違うのでJSONを解釈できない」というエラーが…
    API定義書に従ってコード生成したのに…?

    View full-size slide

  27. サーバが返すJSONが型に厳密ではなかった
    ● 文字列として扱いたいのに、数値として送信してくる
    場合がある
    ● 数値として扱いたいのに、文字列として送信してくる
    場合がある
    ● 正しく送信してくる場合もある
    →文字/数値の扱いが不定のJSONを柔軟に
     受け取れるようにする必要がある
    (サーバを直すというのは今回自身に課したレギュレーション的にナシ)

    View full-size slide

  28. 型を柔軟に受け取るには、JSON解析後の型当てはめを自分
    で実装する必要がある
    Response
    JSON
    Go
    構造体
    型付き
    JSON解析&型当てはめ
    Response
    JSON
    Go
    構造体
    なんでも型
    JSON解析
    Go
    構造体
    型付き
    型当てはめ
    この処理を今回のケースに合わせて自作する必要がある

    View full-size slide

  29. OpenAPI、ダメかも
    openapi.yml
    API定義
    Goの
    通信関連
    コード
    openapi-generator
    Baal
    API定義
    yaml-generator
    Response
    JSON
    Go
    構造体
    型付き
    JSON解析&型当てはめ
    OpanAPIが生成したコードがブラックボッ
    クスで、生成物をカスタマイズできなかっ

    Goであるがゆえに難しい

    View full-size slide

  30. OpenAPIを使うのをやめる

    View full-size slide

  31. そもそもなぜOpenAPIを使ったか?
    Goの構造体と通信を担うコードを生成するのは難しいと感じたから
    既存の仕組みにはなるべく乗っかるべきだと思っていたから
    openapi.yml
    API定義
    Goの
    通信関連
    コード
    openapi-generator
    Baal
    API定義
    yaml-generator
    Baal
    API定義
    Goの
    通信関連
    コード
    client-generator (自作)
    ここを自前で作るのは難しい(と思っていた)
    これを辞めて
    これをやることにした
    ツールを辞めて自前で作ることで、
    JSONの型について
    柔軟なしくみを作れるようになる

    View full-size slide

  32. 実は、知らない間に実力がついていた
    openapi.yml
    API定義
    Goの
    通信関連
    コード
    openapi-generator
    Baal
    API定義
    yaml-generator
    Baal
    API定義
    Goの
    通信関連
    コード
    client-generator (自作)
    これを作るのに必要な要素
    - Baalパーサを扱うこと
    - テンプレートエンジンを扱うこと
    これを作るのに必要な要素
    - Baalパーサを扱うこと
    - テンプレートエンジンを扱うこと
    難しいと思っていたことが
    もうできるようになっていた

    View full-size slide

  33. コード生成を自前で作ることにした
    ● 結果として、Baal API定義書からコード生成するジェネレータを自前で
    書けるようになった。
    ● API通信の土台がやっと完成した
    AI開発のスタート地点に

    View full-size slide

  34. 教訓
    ● 初心者意識はいつまでも持つものじゃない
    ● Goは既存のコードをカスタマイズするのが難しい
    ● 既存のツールの恩恵にあやかろうとしすぎず、
    自分に必要な物だけを自前で用意する方が良い時もある
    ● がっつり失敗したほうが身につく物もある

    View full-size slide

  35. なぜこんなことをしたのか
    ● 今現在の仕事で得られる経験がなくなってしまった
    -> 異動の希望?
    -> 転職?
    -> それ以外にもやりようはあるのではないか
    ● 数年かけて仕事を覚え、効率化し、余白を作った
    余白を使い、今のプロジェクトのまま新しい経験が得られる題材を自分で
    設定した

    View full-size slide