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

GraphQL導入への技術選定

松田
September 25, 2024

 GraphQL導入への技術選定

松田

September 25, 2024
Tweet

More Decks by 松田

Other Decks in Technology

Transcript

  1. 2022.10
 2022.10〜 
 Retty登壇用テンプレート 
 Retty株式会社 名前なまえ 
 Copyright ©2024 Retty,

    Inc. 
 Copyright ©2024 Retty, Inc. 
 Rettyについて 
 4
 iOS Android Web
  2. Copyright ©2024 Retty, Inc. 
 この発表について 
 • 使用している技術、抱えていた課題 


    • GraphQLを選定した理由 
 • 実装するにあたってのライブラリの選定理由 
 • 導入で得られたメリット 
 5

  3. サービス構成
 マイクロサービス群 アプリバックエンド アプリ • Kotlin/JVM • Jersey Android/iOS •

    状態管理はRedux • Go Protocol Buffers / gRPC REST API Webチームがメイン アプリチームがたまに触る アプリチームがメイン Webチームは殆ど触らない
  4. GraphQLを選定した理由
 アプリバックエンド ↔アプリ間での型定義の問題 • オーバーフェッチを避ける為に複数のユーザー型があった ◦ ユーザー画面に使用するユーザー型 ◦ 店舗画面の投稿一覧に使用するユーザー型 ◦

    投稿画面に使用するユーザー型 • クライアントの状態管理の Reduxでの問題 ◦ ローカルで管理する型にマッピングする処理がサーバー定義の型分ある ◦ このReduxのActionではこの値は取得できるんだっけ …?という考慮が発生
  5. GraphQLを選定した理由
 コード生成の問題 • iOS ◦ 独自のツールを使用 ◦ サーバーコードをリフレクションして、 Swiftのリクエストコードと、レスポンスの型を作成 ◦

    メンテナンスコスト ▪ CocoaPods -> Swift Package Manager対応 ▪ 最近はSwift Concurrencyの対応 • Android ◦ サーバーの定義をコピーしてきて使用 ◦ サーバーとクライアントの定義がずれる
  6. GraphQL実装の技術選定・調査
 バックエンドを実装する場所を決める • 既存のバックエンドに統合 • 新規にサーバーを立ち上げる 既存のバックエンドに統合する事にした • 新規バックエンドにすると ◦

    Goを使用して社内のメイン言語と合わせられる ◦ 既存バックエンドを一気に廃止しきれない ▪ 積極開発されなくなり、開発できる人が減り、メンテナンスが困難になる事が想定される
  7. graphql-java-codegen の修正部分 GraphQL実装の技術選定・調査
 restaurant { id: Id reservationAttributes { ~

    } } 親に含まれない内部的な 値を渡したい CompletionStage<ReservationAttributes> ↓ CompletionStage<DataFetcherResult<ReservationAttributes>>
  8. セキュリティ • Query depth & Query complexity ◦ コストを設定し、大きいリクエストを行えないようにすることが可能 ◦

    正規のリクエストもコストに気を配ったりしなければならず面倒 • Persisted Queries ◦ 事前にクエリを登録しておき、クエリの hashだけを送ってリクエストする ◦ アプリケーションのリリースビルド時にクエリを CIでAmazon S3に送信し、それをサー バー側で参照 ◦ 外部からアクセスできない開発環境はすべてのクエリを許可している GraphQL実装の技術選定・調査

  9. 余談 検討時に認識していなかった • Signed Query ◦ クエリに署名してサーバー側で署名を検証する ◦ Persisted Queriesとの比較

    ▪ クエリをS3にアップロードする手間が無い ▪ Persisted Queriesはhashだけ送るので、通信量が少ない GraphQL実装の技術選定・調査

  10. セキュリティ • Introspection ◦ スキーマの構造を返す機能 ◦ 開発環境以外では、返さないように設定 • スタックトレース ◦

    何も設定しないとエラーをそのままクライアントに返す ◦ 意図せず秘匿情報を返す可能性も ◦ サーバー側でエラーを記録し、必要なものだけクライアントに返す用のレスポンスにマッピングし、 他のエラーは返さないように設定 GraphQL実装の技術選定・調査

  11. override fun name( restaurant: QlRestaurant, env: DataFetchingEnvironment ): CompletionStage<DataFetcherResult<String?>> {

    /** DataLoaderを呼ぶ ** / } override fun status( restaurant: QlRestaurant, env: DataFetchingEnvironment, ): CompletionStage<DataFetcherResult<QlRestaurantStatus?>> { /** ~ ** / } override fun tel( restaurant: QlRestaurant, env: DataFetchingEnvironment, ): CompletionStage<DataFetcherResult<String?>> { /** ~ ** / } フィールドごとに並列に実行される為、実装を気にせず並列に処理される 例) 導入の成果
 
 restaurant { id: Id name: String status: Status tel: String } GraphQL + DataLoaderで 実行速度が改善
  12. 表示速度 • before ◦ 店舗の表示に使用している旧 APIは1秒程かかっていた ◦ 追加で0.1秒程かかる3つのAPIを呼び出し • after

    ◦ GraphQLに移行後は全て合わせて 400ms程で取得 ◦ 体感できる程早く 導入の成果

  13. まとめ • Rettyアプリでは以下の問題が解決 ◦ コードの自動生成による開発効率化 ◦ クライアントでのキャッシュ ◦ 複雑化した型定義 ◦

    表示時間の短縮 チーム構成、技術課題、実装の思想を明確化し、適切な技術選定を 導入の成果