Slide 1

Slide 1 text

minne Android における GraphQL の取り組み 田尻宗準 / Tajiri Munenori 2021.08.05 Android Meetup 【ZOZOテクノロジーズ × サイバーエージェント × GMOペパボ】 1

Slide 2

Slide 2 text

Handmade is Good.
 家具も、服も、食べ物も。
 ぜんぶ、だれかがつくったものだ。 


Slide 3

Slide 3 text

3 自己紹介 minne事業部 マーケットグループ 2020年 新卒入社 田尻 宗準 Tajiri Munenori (mune) ● Android アプリ開発しています ● 最近、特徴絞り込み機能をリリースしました 🎉 ● ビールが好きです🍺 ● Netflix でドラマを見るのにハマっています ● Twitter: _mune0903

Slide 4

Slide 4 text

4 今日お話しすること 1. GraphQL とは何か 2. なぜ minne で GraphQL を採用したのか 3. Apollo GraphQL client を使ってみる 4. GraphQL を採用して良かったこと 5. まとめ

Slide 5

Slide 5 text

5 1. GraphQL とは何か

Slide 6

Slide 6 text

6 GraphQL とは何か • Facebook 製 • クライアント / サーバー通信のための言語仕様 • クエリ言語(SQL と問い合わせ言語という点で共通) • Query(SELECT) • Mutation(INSERT,UPDATE,DELETE) • Subscription(リアルタイムにデータの更新情報を受け取る) • スキーマ言語 • GraphQL API の型システムを定義します • クライアントがアクセスできる、存在しうるデータの完全な集合を記述する • スキーマをもとにレスポンスが生成される

Slide 7

Slide 7 text

7 GraphQL とは何か スキーマ Person 型は id,age,name の3つのフィールドを持つ クエリ 必要なフィールドだけを クエリの形で記述する レスポンス クエリで指定したデータが レスポンスとして返ってくる 🎉 type Person { id: ID! age: Int! name: String! } query { person { id name } } { “data”: { “id”: “100” “name”: “mune” } }

Slide 8

Slide 8 text

8 GraphQL とは何か スキーマ Person 型は id,age,name の3つのフィールドを持つ クエリ クエリとレスポンスデータの 構造がほぼ似ており 情報量が多くてわかりやすい レスポンス type Person { id: ID! age: Int! name: String! } query { person { id name } } { “data”: { “id”: “100” “name”: “mune” } }

Slide 9

Slide 9 text

9 GraphQL とは何か レスポンス クエリ クエリドキュメントには複数のクエリを書く ことができます。実行できるオペレーションは 一度にひとつだけ ひとつのクエリであらゆる種類のデータを 一度に取得することができる 🎉

Slide 10

Slide 10 text

10 2. なぜ minne で GraphQL を 採用したのか

Slide 11

Slide 11 text

minne では API の柔軟性、型による堅牢性における恩恵を受けるため GraphQL を採用しています。 なぜ minne で GraphQL を採用したか 11 柔軟性 クエリ言語を操作してデータを操 作するため、クライアントは 本当に必要なリクエストのみを送 ることができます。 堅牢性 11 スキーマによる型付けにより 型安全で運用ができる。 アクセスができ、存在しうるデータ の完全な集合。

Slide 12

Slide 12 text

12 なぜ minne で GraphQL を採用したか RESTの課題①:過剰な取得 GET https://api.github.com/user 39 のキーからなる 膨大なレスポンスが 流れてくる

Slide 13

Slide 13 text

13 なぜ minne で GraphQL を採用したか RESTの課題①:過剰な取得 GET https://api.github.com/user login, avatar_url, name のみ必要な場合、無駄な データをネットワークを 介して取得してしまう

Slide 14

Slide 14 text

14 なぜ minne で GraphQL を採用したか GraphQL なら? GitHub v4 GraphQL API

Slide 15

Slide 15 text

15 なぜ minne で GraphQL を採用したか GraphQL なら? GitHub v4 GraphQL API 必要なフィールドのみ指定します

Slide 16

Slide 16 text

16 なぜ minne で GraphQL を採用したか GraphQL なら? GitHub v4 GraphQL API 要求したデータのみがレスポンスに含まれる 残りの余分な 36 ものフィールドをネットワークを介して取得しなくて済む

Slide 17

Slide 17 text

17 なぜ minne で GraphQL を採用したか GraphQL なら? GitHub v4 GraphQL API ① 欲しいデータを受け取れるようにクエリを作成 ①

Slide 18

Slide 18 text

18 なぜ minne で GraphQL を採用したか GraphQL なら? GitHub v4 GraphQL API ① 欲しいデータを受け取れるようにクエリを作成 ② 望んだデータのレスポンスを受け取ることができる ① ②

Slide 19

Slide 19 text

19 なぜ minne で GraphQL を採用したか GraphQL なら? GitHub v4 GraphQL API ① 欲しいデータを受け取れるようにクエリを作成 ② 望んだデータのレスポンスを受け取ることができる  余分なデータを取得しないことで、より高速にレスポンスを受け取れる可能性あり ① ②

Slide 20

Slide 20 text

20 なぜ minne で GraphQL を採用したか 先ほど取得した login, avatar_url, name に加えて follower 数, following 数, gist 名も欲しい! RESTの課題②:過小な取得

Slide 21

Slide 21 text

21 なぜ minne で GraphQL を採用したか 先ほど取得した login, avatar_url, name に加えて followers 数、following 数、gist 名も欲しい! RESTの課題②:過小な取得 GET https://api.github.com/user GET https://api.github.com/users/mune0903/followers GET https://api.github.com/users/mune0903/following GET https://api.github.com/users/mune0903/gists 4回のリクエストが 必要になる

Slide 22

Slide 22 text

22 なぜ minne で GraphQL を採用したか エンドポイントの数だけ 大きなレスポンスを受け取る 羽目になる可能性がある😇 レスポンスも遅くなる RESTの課題②:過小な取得

Slide 23

Slide 23 text

23 なぜ minne で GraphQL を採用したか 本当に必要だったのは login, avatar_url, name followers 数, following 数,gist 名だけ… RESTの課題②:過小な取得

Slide 24

Slide 24 text

24 なぜ minne で GraphQL を採用したか GraphQL なら? GraphQL では一度のリクエストで必要なデータ全てを要求することができる

Slide 25

Slide 25 text

25 なぜ minne で GraphQL を採用したか • クライアントに変更が加わると新たなエンドポイントを生やす必要がある • リクエスト回数を最適化しようとするとエンドポイントの 数が膨れ上がる RESTの課題③:エンドポイントの管理

Slide 26

Slide 26 text

26 なぜ minne で GraphQL を採用したか • クライアントに変更が加わると新たなエンドポイントを生やす必要がある • リクエスト回数を最適化しようとするとエンドポイントの 数が膨れ上がる GraphQL は単一のエンドポイントしか存在しない 単一のエンドポイントに送られるクエリに基づいてデータを統合する RESTの課題③:エンドポイントの管理

Slide 27

Slide 27 text

minne では API の柔軟性、型による堅牢性における恩恵を受けるため GraphQL を採用しています。 なぜ minne で GraphQL を採用したか 27 柔軟性 クエリ言語を操作してデータを操 作するため、クライアントは 本当に必要なリクエストのみを送 ることができます。 堅牢性 27 スキーマによる型付けにより 型安全で運用ができる。 アクセスができ、存在しうるデータ の完全な集合。

Slide 28

Slide 28 text

28 minne は絶賛 GraphQL に移行中💪

Slide 29

Slide 29 text

29 3. Apollo GraphQL client

Slide 30

Slide 30 text

30 Apollo GraphQL client • GraphQL で HTTP クライアントを実装するために使用されます • OkHttp3 + Apollo GraphQL client • スキーマとクライアントからのリクエスト情報(クエリ)をもとに 自動でクライアントが利用する型をもつモデルを生成してくれる • Relay は React と React Native だけ対応 • Android は Apollo がデファクト? Android における GraphQL クライアント

Slide 31

Slide 31 text

31 Apollo GraphQL client plugin にはプロジェクトをビルドしたときにモデルを自動生成するためのコンパイラが 含まれています🛠 build.gradle に plugin の追加

Slide 32

Slide 32 text

32 Apollo GraphQL client https://github.com/apollographql/apollo-android/releases build.gradle に依存関係の追加

Slide 33

Slide 33 text

33 Apollo GraphQL client Apollo GraphQL client は Coroutines をサポートしている build.gradle に依存関係の追加

Slide 34

Slide 34 text

34 Apollo GraphQL client 指定しないと Java のモデルクラスが自動生成されます https://www.apollographql.com/docs/android/tutorial/01-configure-project/#configure-kotlin Kotlin クラスを自動生成させる

Slide 35

Slide 35 text

35 Apollo GraphQL client • Apollo CLI を使って簡単に取得ができる GraphQL Schema の追加 Build Variants が複数ある minne ではエンドポイントをその都度変えるの大変なので 別途シェルスクリプト書いて便利にしています! schema.json の置き場所例 datasource/api/src/main/graphql/com/hoge/datasource/api/graphql/schema.json

Slide 36

Slide 36 text

36 Apollo GraphQL client GraphiQL を使ってクエリ書く

Slide 37

Slide 37 text

37 Apollo GraphQL client GraphiQL を使ってクエリ書く 正しくないクエリを書くと親切にエラーを教えてく れます󰢃

Slide 38

Slide 38 text

38 Apollo GraphQL client GraphiQL を使ってクエリ書く 正しいクエリを書いて正しいレスポンスを 受け取れたら󰢏

Slide 39

Slide 39 text

39 Apollo GraphQL client • schema.json と同じディレクトリ配下に Viewer.graphql を作成する • 先ほど GraphiQL で書いたクエリをコピペします!!1 プロジェクトにクエリを追加する

Slide 40

Slide 40 text

40 Apollo GraphQL client • schema.json と同じディレクトリ配下に Viewer.graphql を作成する • 先ほど GraphiQL で書いたクエリをコピペします!!1 プロジェクトにクエリを追加する

Slide 41

Slide 41 text

41 一回ビルドします🛠

Slide 42

Slide 42 text

42 Apollo GraphQL client モデルクラスが自動生成される これでアプリからクエリを実行できる準備が整いました 🎉

Slide 43

Slide 43 text

43 Apollo GraphQL client クエリを実行する

Slide 44

Slide 44 text

44 Apollo GraphQL client ① 生成されたモデルに必要な引数等を渡して ApolloApiClient を使ってクエリ実行する クエリを実行する ①

Slide 45

Slide 45 text

45 Apollo GraphQL client ① 生成されたモデルに必要な引数等を渡して ApolloApiClient を使ってクエリ実行する ② レスポンスをハンドリングしてあげる • GraphQL はエラーであっても 200 を返すので、ステータスコードで ハンドリングできないので注意 クエリを実行する ① ②

Slide 46

Slide 46 text

46 Apollo GraphQL client Apollo の依存を外部に漏らさない UseCase, ViewModel に Apollo の依存関係が漏れるのは良くないので アプリ独自の Entity にmap してあげています

Slide 47

Slide 47 text

47 4. GraphQL を採用して 良かったこと

Slide 48

Slide 48 text

48 GraphQL を採用して良かったこと • GraphQL API の便利ツール GraphiQL が便利すぎる • GitHub の GraphiQL • https://docs.github.com/ja/graphql/overview/explorer • GraphQL のイントロスペクション機能によって GraphiQL 自体がドキュメント • あらゆる GraphQL API が API スキーマの詳細を返してくれる 開発体験が良い

Slide 49

Slide 49 text

49 GraphQL を採用して良かったこと 開発体験が良い 入力補完など

Slide 50

Slide 50 text

50 GraphQL を採用して良かったこと 開発体験が良い イントロスペクション機能によってスキーマの詳細がわかる

Slide 51

Slide 51 text

51 GraphQL を採用して良かったこと • minne web は Ruby on Rails 製のアプリケーション • ※ Web フロント刷新中 • Web は2011年に rails new され爆誕 • iOS は2012年に爆誕 • Android は2013年に爆誕 ※ Initial commit された年であってリリース年と異なる可能性があります minne の歴史(ざっくり)

Slide 52

Slide 52 text

52 GraphQL を採用して良かったこと • minne web は Ruby on Rails 製のアプリケーション • ※ Web フロント刷新中 • Web は2011年に rails new され爆誕 • iOS は2012年に爆誕 • Android は2013年に爆誕 ※ Initial commit された年であってリリース年と異なる可能性があります Web API の開発はサーバーサイド(Web)のエンジニアがほとんど担当 クライアントサイドのエンジニアが一から Web API の開発に参画する機会・体制は あまりなかった minne の歴史(ざっくり)

Slide 53

Slide 53 text

53 GraphQL を採用して良かったこと 以前の Web API 開発スタイル Web API 開発者 Web API 利用者 設計 実装 実装 検証 完成 完成 Web API の実装が 完了していないと利用者 は実装を始められない • API の実装がある程度進まない とクラアントの実装に着手しづら い • 設計を開発者に委ねている 作り 直しも起こり得る • 単方向的な関わり方 ❌ ⭕ WEB+DB PRESS Vol.108 第1章 スキーマ駆動開発とは何か より

Slide 54

Slide 54 text

54 GraphQL を採用して良かったこと • 各プラットフォームから1名ずつ代表者決めて 「GraphQL会」発足 • サーバーサイド、iOS、Android、Webフロント • 今後の Web API 開発について • 新規開発は基本的に GraphQL API を使う • 大まかな開発フロー • GraphQL スキーマを実装する人はサーバサイドのエンジニアに限定しない • スキーマレビューのルール エラーハンドリング、ページネーション、命名規則などなど … GraphQL 導入するにあたって

Slide 55

Slide 55 text

55 GraphQL を採用して良かったこと • 各プラットフォームから1名ずつ代表者決めて 「GraphQL会」発足 • サーバーサイド、iOS、Android、Webフロント • 今後の Web API 開発について • 新規開発は基本的に GraphQL API を使う • 大まかな開発フロー • GraphQL スキーマを実装する人はサーバサイドのエンジニアに限定しない • スキーマレビューのルール サーバーサイド・クライアントサイドのエンジニアが集まって GraphQL の導入を いっしょに促進し、GraphQL によってより良い体制を築けた GraphQL 導入するにあたって

Slide 56

Slide 56 text

56 GraphQL を採用して良かったこと 現在の Web API の開発スタイル Web API 開発者 Web API 利用者 スキーマ設計 実装 実装 検証 設計 設計 ⭕ ❌ Web API 開発者 Web API 利用者 設計 実装 実装 検証 完成 完成 Web API の実装が完了 していないと利用者は実 装を始められない ❌ ⭕ Web API の実装を 待たずに利用者も 実 装を始められる WEB+DB PRESS Vol.108 第1章 スキーマ駆動開発とは何か より

Slide 57

Slide 57 text

57 まとめ 1. GraphQL とは何か • クライアント / サーバー通信のための言語仕様 2. なぜ minne で GraphQL を採用したのか • 柔軟性、堅牢性の恩恵を受けるため 3. Apollo GraphQL client を使ってみる • そんなに難しくないよ! 4. GraphQL を採用して良かったこと • 開発体験が良い • サーバーサイド・クライアントサイドでの関わり方が双方向なものに変化した

Slide 58

Slide 58 text

58 Thank You! Thank You! #android_meetup