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

GoのGraphQLライブラリgqlgenを使ったリスト取得の実装.pdf

Avatar for fujiwaram fujiwaram
August 21, 2023
170

 GoのGraphQLライブラリgqlgenを使ったリスト取得の実装.pdf

Avatar for fujiwaram

fujiwaram

August 21, 2023
Tweet

Transcript

  1. Copyright©HRBrain, Inc. All Rights Reserved 2 ・名前:藤原 学 ・現在   ・HRBrainのタレントマネジメントチームでテックリードとして従事

      ・バックエンドエンジニア ・これまで  ・SESで10年くらいガラケーとかスマホを作ってた  ・2018年12月からHRBrainにジョイン   ・社員名簿サービスの新規立ち上げなどに関わる 発表者紹介
  2. Copyright©HRBrain, Inc. All Rights Reserved gqlgenをインストールし以下のコマンドを実行するとスケルトンを作成してくれる go run github.com/99designs/gqlgen init

    schema.graphqlsのスキーマを変更して以下のコマンドを実行するとスキーマに合わせた型 定義やResolverが呼ばれるまでの処理を自動生成してくれる go run github.com/99designs/gqlgen 詳細な手順はこちらを参照 https://gqlgen.com/getting-started/ 7 スキーマを元にコードを自動生成
  3. Copyright©HRBrain, Inc. All Rights Reserved クエリを実行するときに呼ばれるResolverという関数がある ここは自動生成で空の関数だけが用意されるので、中身の実装が必要 SQLを実行し、DBから取得した値を変数に詰めて返すだけ 上記はsqlxを使用した実装例 8

    Resolverの実装 Resolverはフィールド毎に用意することが可能 Query直下のフィールドは必ずResolverが生成される スキーマの定義でResolverを用意するかどうかを指定できる
  4. Copyright©HRBrain, Inc. All Rights Reserved ユーザーの一覧を取得して、さらにユーザー配下の友達の一覧を取得するクエリ このときのResolverの呼ばれ方👇 9 もう少し複雑なクエリ スキーマ

    実行するクエリ - queryResolver.UserList:ユーザーの一覧を取得(ユーザー1,2,3,4…) - userResolver.Friends:ユーザー1の友達一覧を取得 - userResolver.Friends:ユーザー2の友達一覧を取得 - userResolver.Friends:ユーザー3の友達一覧を取得 - userResolver.Friends:ユーザー4の友達一覧を取得    ︙
  5. Copyright©HRBrain, Inc. All Rights Reserved 10 入れ子の一覧取得クエリで発生する課題 - queryResolver.UserList:ユーザーの一覧を取得(ユーザー1,2,3,4…) 👉SELECT

    * FROM users; - userResolver.Friends:ユーザー1の友達一覧を取得 👉SELECT * FROM users WHERE id IN (2, 3, 4); - userResolver.Friends:ユーザー2の友達一覧を取得 👉SELECT * FROM users WHERE id IN (1); - userResolver.Friends:ユーザー3の友達一覧を取得 👉SELECT * FROM users WHERE id IN (1, 6); - userResolver.Friends:ユーザー4の友達一覧を取得 👉SELECT * FROM users WHERE id IN (1, 8);    ︙ こうなる GraphQLでよく課題となるN+1問題がこれ
  6. Copyright©HRBrain, Inc. All Rights Reserved Dataloaderという仕組みが用意されている 同じクエリをまとめて実行してくれる - userResolver.Friends:ユーザー1の友達一覧を取得 👉SELECT

    * FROM users WHERE id IN (2, 3, 4); - userResolver.Friends:ユーザー2の友達一覧を取得 👉SELECT * FROM users WHERE id IN (1); - userResolver.Friends:ユーザー3の友達一覧を取得 👉SELECT * FROM users WHERE id IN (1, 6); - userResolver.Friends:ユーザー4の友達一覧を取得 👉SELECT * FROM users WHERE id IN (1, 8); - userResolver.Friends:ユーザー1,2,3,4,...の友達一覧を取得 👉SELECT * FROM users WHERE id IN (2, 3, 4, 1, 6, 8); 11 N+1問題の解決策① 詳しくはこちら https://gqlgen.com/reference/dataloaders/
  7. Copyright©HRBrain, Inc. All Rights Reserved ◯ Resolverを分けないで親の階層でのデータ取得時に一緒に取得する 分かりやすいけど、GraphQLの利点である必要なデータだけ取得することができなくな る ◯

    ただ、今回の例では親と子が同じデータ(User)なので、親で取得したデータをオンメモリ で保持しておき、各子供のResolverで一致するデータを返して上げるという方法もあり 12 N+1問題の解決策②