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?
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
WS:Subscribe GraphQL Document Subscriptions Server (WS) GraphQL Server PARSE GraphQL Language VALIDATE Schema EXECUTE Resolvers Event System @_kamlesh_ @peri_nikhil
Subscriptions Server (WS) WS:Subscribe GraphQL Document GraphQL Server PARSE GraphQL Language VALIDATE Schema EXECUTE Resolvers Event System @_kamlesh_ @peri_nikhil
Subscriptions Server (WS) GraphQL Document GraphQL Server PARSE GraphQL Language VALIDATE Schema EXECUTE Resolvers Event System @_kamlesh_ @peri_nikhil Event Stream
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
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
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
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
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
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
“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