Slide 1

Slide 1 text

1 GoのGraphQLライブラリgqlgenを使った リスト取得の実装 藤原 学

Slide 2

Slide 2 text

Copyright©HRBrain, Inc. All Rights Reserved 2 ・名前:藤原 学 ・現在   ・HRBrainのタレントマネジメントチームでテックリードとして従事   ・バックエンドエンジニア ・これまで  ・SESで10年くらいガラケーとかスマホを作ってた  ・2018年12月からHRBrainにジョイン   ・社員名簿サービスの新規立ち上げなどに関わる 発表者紹介

Slide 3

Slide 3 text

Copyright©HRBrain, Inc. All Rights Reserved ChatGPTに聞いてみた 3 GraphQLって良いよね

Slide 4

Slide 4 text

Copyright©HRBrain, Inc. All Rights Reserved GraphQLのスキーマ定義の例。プログラミング言語の定義に近くて分かりやすい。 4 自分が好きなところ

Slide 5

Slide 5 text

Copyright©HRBrain, Inc. All Rights Reserved https://gqlgen.com/ https://github.com/99designs/gqlgen GraphQLサーバを簡単に作るためのGo製のライブラリ ・GraphQLスキーマからコードを自動生成してくれる ・型安全 ・GitHubのStar数が9.1K(2023/8/21時点) 今日は、こちらを使った実装について話します。 5 gqlgen

Slide 6

Slide 6 text

Copyright©HRBrain, Inc. All Rights Reserved こんなGraphQLスキーマ https://github.com/fujiwaram/gqlgen-list-example/blob/main/graph/schema.graphqls 実際に動かしてみる 6 ユーザー一覧の取得の例

Slide 7

Slide 7 text

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 スキーマを元にコードを自動生成

Slide 8

Slide 8 text

Copyright©HRBrain, Inc. All Rights Reserved クエリを実行するときに呼ばれるResolverという関数がある ここは自動生成で空の関数だけが用意されるので、中身の実装が必要 SQLを実行し、DBから取得した値を変数に詰めて返すだけ 上記はsqlxを使用した実装例 8 Resolverの実装 Resolverはフィールド毎に用意することが可能 Query直下のフィールドは必ずResolverが生成される スキーマの定義でResolverを用意するかどうかを指定できる

Slide 9

Slide 9 text

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の友達一覧を取得    ︙

Slide 10

Slide 10 text

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問題がこれ

Slide 11

Slide 11 text

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/

Slide 12

Slide 12 text

Copyright©HRBrain, Inc. All Rights Reserved ◯ Resolverを分けないで親の階層でのデータ取得時に一緒に取得する 分かりやすいけど、GraphQLの利点である必要なデータだけ取得することができなくな る ◯ ただ、今回の例では親と子が同じデータ(User)なので、親で取得したデータをオンメモリ で保持しておき、各子供のResolverで一致するデータを返して上げるという方法もあり 12 N+1問題の解決策②

Slide 13

Slide 13 text

Copyright©HRBrain, Inc. All Rights Reserved gqlgenを使えば実装量少なめでGraphQLサーバを作ることができます。 興味を持った方はぜひ一度試してみてください! 今回使用したデモやソースコードは以下に上げてます。 https://github.com/fujiwaram/gqlgen-list-example 13 まとめ

Slide 14

Slide 14 text

No content