Slide 1

Slide 1 text

Real-Time applications with GraphQL @joe_re 1/24

Slide 2

Slide 2 text

Self introduction twitter: @joe_re github: @joe-re GraphQL Tokyo Organizer Work for ClassDo Live in Singapore 2/24

Slide 3

Slide 3 text

Today, I'm going to talk about.. GraphQL Subscriptionとは何か GraphQL Subscription採用におけるメリット 運用していく中で、自分達が気をつけているポイントを4つのプラクティスとして紹介 But I'm not going to talk about.. あくまでGraphQL Subscriptionの運用、設計の話をするので、 個別の機能要件に関連する話はしません(そこのつらみはたくさんあるけど) 自分達のアプリケーション特性に基づいた話を運用の経験からお話します。 全てのアプリケーションにあてはまるという主張ではありません 3/24

Slide 4

Slide 4 text

ClassDo 教育に特化したオンラインミーティングサービス オンラインの授業を行う上ではリアルタイムコミュニケーションが超重要 クライアントから呼び出しているAPIのほぼ全てはGraphQL 勉強会の用途なら無料で使えるように提供できます。大人数向けのカンファレンスには 向いていないけど、少人数のセッションを運営している方などぜひ! We're hiring!(特にGraphQLでリアルタイムなインタラクションを実装してみたい方!) 4/24

Slide 5

Slide 5 text

DEMO 5/24

Slide 6

Slide 6 text

What is GraphQL Subscription QueryやMutationと同じくGraphQLのオペレーションの1つ Schemaの変更をリアルタイムにサーバより受け取るためにコネクションを作る (WebSocketが主流) QueryやMutationと違い、長くライフサイクルを持つオペレーションになる 6/24

Slide 7

Slide 7 text

Simple example ある記事に対してコメントの追加を検知する subscription AddedComment { addedComment { id text author article } } 7/24

Slide 8

Slide 8 text

Why GraphQL Subscription is good with us 当初はリアルタイムな同期を想定していないエンティティも、 機能開発によって必要になることが多い 新しく追加される同期処理に対してインタラクションの設計の手間がかからない Query, Mutationと同じスキーマを共有しているので、GraphQLスキーマ上に存在する 全てのエンティティがsubscribableだと考えられるようになる 8/24

Slide 9

Slide 9 text

The actual case for everything can be subscribable 9/24

Slide 10

Slide 10 text

Our architecture of Subscription 10/24

Slide 11

Slide 11 text

Practice 1 Subscriptionでは重い処理は書かない 11/24

Slide 12

Slide 12 text

Subscriptionでは重い処理は書かない Subscriptionへの通知は、Mutationが実行されたあとに即座に通知されることが超重要 この原則を守ることで、ある程度細かいインタラクションを実装せずともまともな ユーザ体験を届けることができる(もちろん機能や程度にはよる) 重い計算処理が必要ならMutationに寄せて、Subscriptionは値を受け取るだけにする Subscription: { // こんな実装はなるべく避ける post: { subscribe(parent, args, { pubsub }) { return pubsub.asyncIterator('post'); }, async resolve(parent, args, context) { // It's too heavy query const posts = await db.getTooHeabyObject({ args: args.foo }) return posts } }, } 12/24

Slide 13

Slide 13 text

Practice 2 Clientでrefetchingやpollingをなるべくしない 13/24

Slide 14

Slide 14 text

Clientでrefetchingやpollingをなるべくしない 1 Mutationの結果、直接変更したエンティティが別のエンティティに影響を与えるケース ってありますよね 簡単な例だとこういうやつ // このMutation の結果 mutation postArticle(input: { title: String! content: String! //.. }) { //.. } type User { id: ID! numberOfPostedArticles: Int! // ここが変わる //... } 14/24

Slide 15

Slide 15 text

Clientでrefetchingやpollingをなるべくしない 2 解決策として一般的に思いつくのは 1. Mutationの後にrefetchingを叩くことで強制的に同期する 2. Mutaionの結果にUpdateが想定されるオブジェクトを含める 3. Subscriptionに変更の検知の全てを委ねる 15/24

Slide 16

Slide 16 text

Clientでrefetchingやpollingをなるべくしない 3 refetchingは重くなる可能性が高い 上記のように簡単な例ならMutationの結果に変更が想定されるオブジェクトを含めれば 変更をリアルタイムに適用できる mutation postArticle(input: { title: String! content: String! //.. }) { //.. author { id, numberOfPostedArticles } } でもこのエンティティの関係がもっと遠いとMutationの返り値で取得するのは難しいか もしれない そもそも変更検知は自分ではなく、リモートのユーザに必要かもしれない 16/24

Slide 17

Slide 17 text

Clientでrefetchingやpollingをなるべくしない 4 前提として、更新の影響を受けるのは別のエンティティのプロパティなので、 demand-driven APIであるGraphQLにおいては更新が必要かどうかは クライアントの関心ごとになる サーバとしては更新のあったエンティティに対して変更の通知さえすれば、 その後それを採用するかどうかはクライアントの責務と言える 同期処理を1つ1つのインタラクションについて個別に考えるより、 更新の発生したエンティティにはとりあえず変更イベントを発火しておいた方が 実装としても楽 17/24

Slide 18

Slide 18 text

Practice 3 Query, MutationとSubscriptionの両方で再利用可能なSchema設計をする 18/24

Slide 19

Slide 19 text

Query, MutationとSubscriptionの両方で再利用可能なSchema設計をする 1 現在見ているタブの同期処理をコマンドベースに考えると.. 19/24

Slide 20

Slide 20 text

Query, MutationとSubscriptionの両方で再利用可能なSchema設計をする 2 Subscriptionにおいてはどのエンティティの変更(CRUD)なのかを考える 20/24

Slide 21

Slide 21 text

Practice 4 Subscriptionが起動するインスタンスはHTTPサーバと分離する 21/24

Slide 22

Slide 22 text

Subscriptionが起動するインスタンスはHTTPサーバと分離する HTTPサーバとSubscriptionサーバとでは消費するコンピュータリソースが違う Subscriptionはコネクションを維持しているので、なるべくスケーリングの頻度は落と して瞬断などが発生する機会を減らしたい もしインスタンスを分けていないと、HTTPサーバの負荷に伴ってスケーリングの変更が された場合にSubscriptionにはその必要がないのに影響を受けてしまう可能性がある 22/24

Slide 23

Slide 23 text

まとめ GraphQLのサブスクリプションはGraphQLのスキーマの世界に リアルタイム性を導入できる 気をつけるべき点を押さえておけば運用も難しくはない 健全なReal-Time Application Lifeを! 23/24

Slide 24

Slide 24 text

Thank you! 24/24