Slide 1

Slide 1 text

フロントエンドでのGraphQL(Mutation)の利用例と今後について SPACEMARKET Tech Meetup #2 2019/7/4 Shunsuke Komaki

Slide 2

Slide 2 text

2 自己紹介 ● Shunsuke Komaki(@shun_komaki) ● フロントエンドエンジニア ● 開発、パフォーマンス改善してます

Slide 3

Slide 3 text

3 話すこと

Slide 4

Slide 4 text

4 話すこと ● これまでの SPACEMARKET での GraphQL ● フロントエンドでの GraphQL 実装 ○ Apollo Client を使った Mutation 実装の話です ● 今後やっていきたいこと ● まとめ

Slide 5

Slide 5 text

5 これまでの SPACEMARKET での GraphQL

Slide 6

Slide 6 text

6 これまでの SPACEMARKET での GraphQL ● React ● Redux / redux-saga ● Apollo Client ● Flow(徐々に TypeScript 移行中) 開発環境

Slide 7

Slide 7 text

7 これまでの SPACEMARKET での GraphQL ● 参照は GraphQL ● 更新は REST API ● 4月にリニューアルした SPACEMARKET EVENT で 更新も GraphQL に!! GraphQL

Slide 8

Slide 8 text

8 これまでの SPACEMARKET での GraphQL 今日は Mutation をメインに話をすすめていきます❗

Slide 9

Slide 9 text

9 これまでの SPACEMARKET での GraphQL 開発については前回のミートアップ記事でも紹介しています。 https://blog.spacemarket.com/news/first-tech-meetup/

Slide 10

Slide 10 text

10 クライアントでの GraphQL 実装

Slide 11

Slide 11 text

11 ライブラリ

Slide 12

Slide 12 text

12 ライブラリ GraphQL のバックエンドとフロントエンドのライブラリです。 フロントエンドでは Apollo Client を使いました。 Apollo のパッケージには開発に役立つ、様々な便利なものがあります。 Apollo

Slide 13

Slide 13 text

13 Apollo Apollo Client 2.0 以降で推奨のキャッシュ実装です。 Redux の Store のようなイメージで扱うことができます。 一度取得したデータを参照したいときは、ネットワーク通信せずにキャッシュを 参照することができます。(Direct Cache Access) apollo-cache-inmemory

Slide 14

Slide 14 text

14 イメージ server サーバーにリクエスト cache 取得済みのデータは ネットワーク通信なしで キャッシュから読み込 みできる Apollo Client レスポンスはキャッシュに保存する

Slide 15

Slide 15 text

15 Error GraphQL エラーやネットワークエラーが発生したときにカスタムロジックを実 装することができます。 エラーログを処理したり、再リクエストしたり。 apollo-link-error

Slide 16

Slide 16 text

16 Error

Slide 17

Slide 17 text

17 ● レスポンスフィールドに独自定義型である UserError 型を定義 ● クライアントはクエリ内にエラーのフィールドに明示的に UserError を書く ● レスポンスに UserError があるときは UI に反映 参考:https://blog.spacemarket.com/code/graphql-ruby-concerns/ バリデーションエラー Error

Slide 18

Slide 18 text

18 エラーのフィールドを書く Error

Slide 19

Slide 19 text

19 Mutation

Slide 20

Slide 20 text

20 Mutation Component

Slide 21

Slide 21 text

21 Mutation Component react-apollo の Mutation Component コンポーネントの render props で mutation の実行可能な関数を受 け取ることができます。

Slide 22

Slide 22 text

22 Mutation Component ● UI コンポーネントは Atomic Design 準拠で別リポジトリで管理 ● Container からは Pages か Organisms で UI コンポーネントを呼ぶだけ ● Molecules や Atoms は呼ばない ● Organisms 以下で複数の Mutation を行いたいイベントハンドラがあるとネス トが深くなりコードが見にくい 課題

Slide 23

Slide 23 text

23 イメージ

Slide 24

Slide 24 text

24 イメージ Container では複数の mutation 関数だけを受け取るようにしたい

Slide 25

Slide 25 text

25 graphql 関数を使う

Slide 26

Slide 26 text

26 graphql 関数を使う react-apollo の graphql

Slide 27

Slide 27 text

27 react-apollo の graphql で関数を渡す ● Component に mutate という関数を渡す ● mutate を実行すると graphql のパラメータに渡した mutation がリクエストさ れる

Slide 28

Slide 28 text

28 react-apollo の graphql で関数を渡す graphql の第二引数の config オブジェクトで名前の変更も可能 参考:https://www.apollographql.com/docs/react/api/react-apollo/#graphqlquery-configcomponent

Slide 29

Slide 29 text

29 複数の関数を扱いたい ● react-apollo の compose で複数の graphql 関数をまとめることができる ● 単体で使うときと同じように props として渡せる compose を使う

Slide 30

Slide 30 text

30 イメージ

Slide 31

Slide 31 text

31 Mutation のレスポンスでキャッシュを更新する

Slide 32

Slide 32 text

32 Direct Cache Access

Slide 33

Slide 33 text

33 更新後のデータを反映する ● readQuery ○ キャッシュからデータを取得する ○ サーバーに通信しない ● wirteQuery ○ キャッシュにデータを書き込む

Slide 34

Slide 34 text

34 イメージ server リクエスト Apollo Client mutation に書いたフィールドを返す 今回なら id と name をもつ addUser mutation addUser { addUser { id name } }

Slide 35

Slide 35 text

35 イメージ キャッシュからデータを取得(readQuery) cache Apollo Client id や name をマージしたオブジェクトをキャッ シュに書き込み(writeQuery)

Slide 36

Slide 36 text

36 イメージ

Slide 37

Slide 37 text

37 課題

Slide 38

Slide 38 text

38 課題 ● 状態管理は Redux まとめて行っていた ● Apollo 導入によりサーバーから取得するデータを Apollo のキャッシュで管理 するので Redux が不要になってきた(と思った) ● React の local state に移していくが Redux のほうが扱いやすい部分もあり Redux も残した ● 結果的に状態管理が散らばり扱いにくくなった

Slide 39

Slide 39 text

39 イメージ Redux Apollo 導入前 データストア Apollo Redux React Apollo 導入後 データストア

Slide 40

Slide 40 text

40 イメージ Redux Apollo 導入前 データストア Apollo Redux React Apollo 導入後 データストア 状態管理が複雑になった!

Slide 41

Slide 41 text

41 課題 ● Redux で管理していた状態を Local State に移していってる ● サーバーから取得したデータは Apollo キャッシュ ● 完全には Redux はなくなっていないが、今のところはこの構成に近づいてき ている Apollo + Local State

Slide 42

Slide 42 text

42 イメージ Apollo Redux React Apollo 導入後 データストア Apollo React

Slide 43

Slide 43 text

43 状態管理の解決案① ● 状態が散らばるのはうれしくない ● Apollo で local state の管理も行うこともありかもしれない ● クエリに @client を追加してローカルに向けることも可能 ● クライアントで resolver を書くことになる 参考:https://www.apollographql.com/docs/react/essentials/local-state Local State も Apollo で

Slide 44

Slide 44 text

44 状態管理の解決案② ● apollo-link-http を使ってデータの取得は GraphQL ● 取得したデータはこれまでどおり Redux 管理 react-apollo を使わずにデータ取得だけを行う?

Slide 45

Slide 45 text

45 今後やっていきたいこと

Slide 46

Slide 46 text

46 今後やっていきたいこと① ● query と mutation のフィールドが完全一致のときにキャッシュが自動で更新 される ● readQuery, writeQuery が必要ない ● 全てのフィールドが一致している必要があるのでフラグメント推奨 参考 : https://www.apollographql.com/docs/react/advanced/caching/#automatic-cache-updates Automatic cache updates

Slide 47

Slide 47 text

47 今後やっていきたいこと② GraphQL に限った話ではないが、スキーマ定義が必要な GraphQLなら スキーマ定義後にフロントとサーバーが同時進行できて開発効率がよくなりそう。 こちらも詳しくは弊社のブログでも触れているのでよかったら見てください。 スキーマ駆動についてのブログ : https://blog.spacemarket.com/code/schema-driven/ スキーマ駆動開発していきたい

Slide 48

Slide 48 text

48 まとめ

Slide 49

Slide 49 text

49 まとめ ● 学習コストは高くなかった ○ ドキュメントが充実している ○ 標準的な機能のみの使用 ● 紹介した機能だけで十分に実装できた ● 参照と更新のどちらも GraphQL ならメリットは大きい ● 開発の進め方などはまだまだ改善できる

Slide 50

Slide 50 text

No content