Slide 1

Slide 1 text

GraphQL Subscription w/ Relay and Action Cable 2018/01/24 アジャイル事業部 年始のご挨拶

Slide 2

Slide 2 text

こんにちは ● Gentaro Terada (@hibariya) ● Works at ESM, Inc. ● A member of Idobata development team ● A college student (engineering) ● https://hibariya.org

Slide 3

Slide 3 text

Apr 2017: Idobata Public GraphQL API

Slide 4

Slide 4 text

Idobata Public GraphQL API の課題 リソースの取得や作成はできるが、メッセージの投稿をリアルタイ ムに知らせるようなイベントの配信はサポートしていないため、 GraphQL とは別の独自の仕組み (非公開 API) を使う必要があ る。

Slide 5

Slide 5 text

Mar 2017: Subscription が仕様に加わる

Slide 6

Slide 6 text

今日お話しすること ● GraphQL の Subscription とはどのようなものか ● Relay Modern + Action Cable で実装するとどんな感じか

Slide 7

Slide 7 text

GraphQL: A query language for your API ● 欲しいものを欲しいだけ、1回のリクエストで取得できる ● リソースの取得 (Query)、破壊的な操作 (Mutation)、Pub/Sub (Subscription) ができる ● スキーマを定義できる ● GraphiQL が便利

Slide 8

Slide 8 text

クエリとレスポンスの例 Request Response

Slide 9

Slide 9 text

関連資料

Slide 10

Slide 10 text

Subscription ● GraphQL に Pub/Sub の仕組みが追加された (2017/3) ● リアルタイムなアプリケーションの API を GraphQL の仕様でカ バーできるようになった ● 通信プロトコルには依存しない ○ WebSocket ○ MQTT ○ etc...

Slide 11

Slide 11 text

今日使うもの: Relay と Action Cable

Slide 12

Slide 12 text

Relay ● React で GraphQL を使うためのフレームワーク ● 各コンポーネントごとに欲しいクエリを書いておくとアプリケー ション全体で1つのクエリにまとめてくれる ● Relay Modern になって Subscription をサポート ● Conventionに従っている限り比較的簡単に開発できる? (個人 の感想)

Slide 13

Slide 13 text

Relay を使った React Component ひとつの message を描画する React Component

Slide 14

Slide 14 text

Relay を使った React Component 必要な情報を GraphQL の fragment として書く (HOC) l

Slide 15

Slide 15 text

Relay を使った React Component アプリケーション全体のクエリの一部として投げられる

Slide 16

Slide 16 text

Action Cable ● Rails が提供する WebSocket による Pub/Sub の仕組み ● アプリケーションプロセスの中で worker が動く ● graphql-ruby が Subscription のバックエンドとして Action Cable に対応している ● ちょっとした Web アプリで使ってみるにはうってつけ

Slide 17

Slide 17 text

Subscription Example with Relay and Action Cable

Slide 18

Slide 18 text

Subscribing New Messages

Slide 19

Slide 19 text

Server Side ● “GraphqlChannel” で Subscription を受け付ける ● 扱いたいイベントを定義 ● Mutation のタイミングでイベントをトリガする

Slide 20

Slide 20 text

“GraphqlChannel” Subscription に使う Action Cable のチャネル。ここでは主に Subscription の登録を行なう。 詳しくは: graphql-ruby.org/subscriptions/action_cable_implementation

Slide 21

Slide 21 text

扱いたいイベントを定義 app/graphql/types/subscription_type.rb

Slide 22

Slide 22 text

イベントを表現する値の型を定義 app/graphql/types/posted_message_type.rb

Slide 23

Slide 23 text

イベントを発火する

Slide 24

Slide 24 text

イベントを発火する app/graphql/mutations/post_message_mutation.rb ● トリガする場所は Mutation の中でなくてもいい ● “User.all” は適切な scope に置き換える

Slide 25

Slide 25 text

Client Side ● 購読したいイベント毎に Subscription クエリを書く ● Subscribe 時にイベント発生時の振舞いを指定する ● Mutation のレスポンスが被るので捨てる (optional)

Slide 26

Slide 26 text

Client Side

Slide 27

Slide 27 text

Subscription クエリを書く app/javascript/subscriptions/MessagePostedSubscription.tsx

Slide 28

Slide 28 text

イベント発生時の振舞いを指定する app/javascript/subscriptions/MessagePostedSubscription.ts

Slide 29

Slide 29 text

振舞いの指定 (Mutation と同じ) ● edgeName: 新しいリソースが、受け取ったペイロードの何とい うフィールド名で入っているか ● type: RANGE_ADD はリソースを connection に追加 ● connectionInfo: どの connection に追加するか ● parentID: connection の親リソースの ID

Slide 30

Slide 30 text

Subscribe It app/javascript/AppMain.ts

Slide 31

Slide 31 text

Mutation のレスポンスが被るので無視

Slide 32

Slide 32 text

Demo ● github.com/hibariya/graphql-subscription-examples ● Subscription 対応ぶんは PR #1

Slide 33

Slide 33 text

実用を踏まえた課題/検討事項 ● Action Cable 単体では対応が難しい問題をどうするか ○ 不意の切断から再接続までのメッセージ取りこぼし ○ パフォーマンス? ● イベント発生時の GraphQL クエリをどこで実行するか ○ Subscription の数 x イベントの数 = たくさん ○ バックグラウンドジョブに移すのがベター ● クライアント側は Action Cable に対応する必要がある

Slide 34

Slide 34 text

Conclusion

Slide 35

Slide 35 text

Conclusion ● GraphQL に Subscriptionが加わったことで、GraphQL の仕様 で作れるアプリケーションの幅が広がった ● 実装にはいくつか注意すべきポイントがある ● デモに使った例はこちら ○ github.com/hibariya/graphql-subscription-examples