Upgrade to Pro — share decks privately, control downloads, hide ads and more …

GraphQL Subscriptions

GraphQL Subscriptions

All of us know GraphQL subscriptions are meant to build real time applications. But what’s behind the scenes is rarely talked about. What are subscriptions really? Why do they exist? How do we make a case for subscriptions to our managers?

Kamlesh Chandnani

April 13, 2019
Tweet

More Decks by Kamlesh Chandnani

Other Decks in Technology

Transcript

  1. Subscriptions return data to the client every time an event

    happens on the server @_kamlesh_ @peri_nikhil
  2. Subsription is a root level type like Query and Mutation

    const typeDefs = gql` type Subscription { postAdded: Post } type Query { posts: [Post] } type Mutation { addPost( author: String, comment: String, ): Post } type Post { author: String comment: String } ` @_kamlesh_ @peri_nikhil
  3. HTTP POST GraphQL Document HTTP Server (Express) GraphQL Server PARSE

    GraphQL Language VALIDATE Schema EXECUTE Resolvers Courtesy: Robert Zhu
  4. HTTP Server (Express) GraphQL Server PARSE GraphQL Language VALIDATE Schema

    EXECUTE Resolvers HTTP POST GraphQL Document @_kamlesh_ @peri_nikhil
  5. HTTP Server (Express) GraphQL Server PARSE GraphQL Language VALIDATE Schema

    EXECUTE Resolvers GraphQL Document @_kamlesh_ @peri_nikhil
  6. HTTP Server (Express) GraphQL Server PARSE GraphQL Language VALIDATE Schema

    EXECUTE Resolvers GraphQL Document @_kamlesh_ @peri_nikhil
  7. HTTP Server (Express) GraphQL Server PARSE GraphQL Language VALIDATE Schema

    EXECUTE Resolvers GraphQL Document @_kamlesh_ @peri_nikhil
  8. HTTP Server (Express) GraphQL Server PARSE GraphQL Language VALIDATE Schema

    EXECUTE Resolvers GraphQL Response @_kamlesh_ @peri_nikhil
  9. HTTP Server (Express) GraphQL Server PARSE GraphQL Language VALIDATE Schema

    EXECUTE Resolvers GraphQL Response @_kamlesh_ @peri_nikhil
  10. WS:Subscribe GraphQL Document Subscriptions Server (WS) GraphQL Server PARSE GraphQL

    Language VALIDATE Schema EXECUTE Resolvers Event System @_kamlesh_ @peri_nikhil
  11. Subscriptions Server (WS) WS:Subscribe GraphQL Document GraphQL Server PARSE GraphQL

    Language VALIDATE Schema EXECUTE Resolvers Event System @_kamlesh_ @peri_nikhil
  12. Subscriptions Server (WS) GraphQL Document GraphQL Server PARSE GraphQL Language

    VALIDATE Schema EXECUTE Resolvers Event System @_kamlesh_ @peri_nikhil Event Stream
  13. Subscriptions Server (WS) GraphQL Document GraphQL Server PARSE GraphQL Language

    VALIDATE Schema EXECUTE Resolvers Event System EVENT @_kamlesh_ @peri_nikhil Event Stream
  14. Subscriptions Server (WS) GraphQL Document GraphQL Server PARSE GraphQL Language

    VALIDATE Schema EXECUTE Resolvers Event System EVENT @_kamlesh_ @peri_nikhil Event Stream
  15. Subscriptions Server (WS) GraphQL Document GraphQL Server PARSE GraphQL Language

    VALIDATE Schema EXECUTE Resolvers Event System EVENT @_kamlesh_ @peri_nikhil Event Stream
  16. Subscriptions Server (WS) GraphQL Document GraphQL Server PARSE GraphQL Language

    VALIDATE Schema EXECUTE Resolvers Event System Executable GraphQL Document @_kamlesh_ @peri_nikhil Event Stream
  17. Subscriptions Server (WS) GraphQL Document GraphQL Server PARSE GraphQL Language

    VALIDATE Schema EXECUTE Resolvers Event System GraphQL Executable Document @_kamlesh_ @peri_nikhil Event Stream
  18. Subscriptions Server (WS) GraphQL Document GraphQL Server PARSE GraphQL Language

    VALIDATE Schema EXECUTE Resolvers Event System GraphQL Executable Document @_kamlesh_ @peri_nikhil Event Stream
  19. Subscriptions Server (WS) GraphQL Document GraphQL Server PARSE GraphQL Language

    VALIDATE Schema EXECUTE Resolvers Event System GraphQL Response @_kamlesh_ @peri_nikhil Event Stream
  20. Subscriptions Server (WS) GraphQL Document GraphQL Server PARSE GraphQL Language

    VALIDATE Schema EXECUTE Resolvers Event System GraphQL Response Event Stream @_kamlesh_ @peri_nikhil
  21. Subscriptions use web sockets under the hood and can be

    accessed using“wss”(websockets) protocol @_kamlesh_ @peri_nikhil wss://graphql.abc.com
  22. In plain words: There is a persistent connection between the

    client and the server and either of them can send data at any point of time. @_kamlesh_ @peri_nikhil
  23. HTTP works in the form of request- response pair, where

    in the client always sends a request and server responds to that request @_kamlesh_ @peri_nikhil
  24. HTTP Server Client Can I have a ? request response

    Here you go @_kamlesh_ @peri_nikhil
  25. In contrast WebSocket(“wss”) is a full duplex connection where either

    the server or the client can send data at any point of time. @_kamlesh_ @peri_nikhil
  26. There are multiple pubsub engine interfaces available:
 •Redis •RabbitMQ •Kafka

    •Google PubSub •MQTT enabled broker •Postgress @_kamlesh_ @peri_nikhil
  27. Won’t a client get ALL events published on the channel?

    @_kamlesh_ @peri_nikhil Client Server PubSub Impl. Event Stream Subscribe Publish Messaging System Publish Subscribe
  28. Client Server Event Stream Subscribe Filter PubSub Impl. Publish Messaging

    System Publish Subscribe @_kamlesh_ @peri_nikhil
  29. 2 steps 1. Write a subscription type on server 2.

    Subscribe to it from your client @_kamlesh_ @peri_nikhil
  30. const resolvers = { Subscription: { matchUpdates: { subscribe: ()

    => pubsub.asyncIterator([‘matches_updated’]), resolve: (payload, args, context) => context.getMatchById({ matchId: args.matchId }), }, }, }; @_kamlesh_ @peri_nikhil
  31. The Resolver Map for a field on the Subscription type

    takes an object, not a function like Query and Mutation. const resolvers = { Query: { matchesQuery: (parent, args, context) => {...} }, }; const resolvers = { Subscription: { matchUpdates: { subscribe: () => {...}, resolve: (payload, args, context) => {...} }, }, }; Function Object with “subscribe” and “resolve” fields @_kamlesh_ @peri_nikhil
  32. The “subscribe” field describes what events you’re concerned with subscribe:

    () => pubsub.asyncIterator([‘matches_updated’]) Client Server PubSub Impl. Event Stream Subscribe Publish Messaging System Publish Subscribe @_kamlesh_ @peri_nikhil
  33. The “resolve” field figures out what data to send to

    the subscribed clients resolve: (payload, args, context) => context.getMatchById({..}) Client Server Event Stream Subscribe PubSub Impl. Publish Messaging System Publish Subscribe @_kamlesh_ @peri_nikhil
  34. “withFilter” allows the server to filter out events that are

    sent to the client based on some arguments subscribe: withFilter( () => pubsub.asyncIterator([‘matches_updated’]), (payload, args) => payload.matchesAffected.some((match) => match.id === args.matchId), ), Client Server Event Stream Subscribe Filter PubSub Impl. Publish Messaging System Publish Subscribe @_kamlesh_ @peri_nikhil
  35. const unsubscribeMatchUpdates = matchQuery.subscribeToMore({ document: subscriptions.MATCH_UPDATES_SUBSCRIPTION, variables: { matchId, },

    updateQuery: (previousResult, { subscriptionData }) => { if (!subscriptionData.data) return previousResult; return { ...previousResult, matchById: { ...previousResult.matchById, ...subscriptionData.data.matchUpdates, }, }; }, }); @_kamlesh_ @peri_nikhil
  36. Use the “updateQuery” function to merge the new data with

    the Apollo store to update the UI @_kamlesh_ @peri_nikhil
  37. const unsubscribeMatchUpdates = matchQuery.subscribeToMore({ document: subscriptions.MATCH_UPDATES_SUBSCRIPTION, variables: { matchId, },

    updateQuery: (previousResult, { subscriptionData }) => { if (!subscriptionData.data) return previousResult; return { ...previousResult, matchById: { ...previousResult.matchById, ...subscriptionData.data.matchUpdates, }, }; }, }); @_kamlesh_ @peri_nikhil
  38. useEffect(() => { const unsubscribeMatchUpdates = matchQuery.subscribeToMore({ document: subscriptions.MATCH_UPDATES_SUBSCRIPTION, variables:

    {matchId}, updateQuery: (previousResult, { subscriptionData }) => { if (!subscriptionData.data) return previousResult; return {...}; }, }); return () => unsubscribeMatchUpdates(); }, [matchId, matchQuery]); @_kamlesh_ @peri_nikhil
  39. But, how do we really make a case to our

    managers? @_kamlesh_ @peri_nikhil manager you
  40. If you want to build a module which requires real

    time updates, then definitely subscriptions is your way to go @_kamlesh_ @peri_nikhil
  41. You can’t really use polling because it won’t be real

    time and you’ll waste server resources @_kamlesh_ @peri_nikhil
  42. Coz, it is the cleaner soulution, utilising all the benefits

    of Apollo cache and the GraphQL schemas @_kamlesh_ @peri_nikhil