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

GraphQL subscriptions

GraphQL subscriptions

fr0gM4ch1n3

July 10, 2018
Tweet

More Decks by fr0gM4ch1n3

Other Decks in Education

Transcript

  1. Preview There are some public APIs to play with: •

    SWAPI - The Star Wars API • Deutsche Bahn • And more …
  2. DataLoader Batching is not an advanced feature, it's DataLoader's primary

    feature
 
 DataLoader provides a memoization cache for all loads userLoader.load(1) .then(user => userLoader.load(user.invitedByID)) .then(invitedBy => console.log(`User 1 was invited by ${invitedBy}`)); Example
  3. DataLoader helper const applyOrder = (idField: string, order: any[], input:

    any[], emptyElement: ObjectConstructor = Object) => { const _input: any[] = [], result = []; for (let index0 = 0, len1 = order.length; index0 < len1; index0++) { _input.push(Object.assign({}, order[index0])); } loop: for (let index1 = 0, len1 = order.length; index1 < len1; index1++) { for (let index2 = 0, len2 = _input.length; index2 < len2; index2++) { if (order[index1] === _input[index2][idField]) { result.push(_input[index2]); index2 = len2; continue loop; } } result.push(new emptyElement()); } return result; };
  4. Overview GraphQL subscriptions have to be defined in the schema,


    just like queries and mutations: type Subscription { commentAdded(repoFullName: String!): Comment }
  5. Overview On the client, subscription queries look just like
 any

    other kind of operation: subscription onCommentAdded($repoFullName: String!){ commentAdded(repoFullName: $repoFullName){ id content } }
  6. Overview The response sent to the client looks as follows:

    { "data": { "commentAdded": { "id": "123", "content": "Hello!" } } }
  7. Server setup server.use('/graphql', bodyParser.json(), graphqlExpress({ schema })); server.use('/graphiql', graphiqlExpress({ endpointURL:

    '/graphql', subscriptionsEndpoint: `ws://localhost:${PORT}/subscriptions` })); const ws = createServer(server); ws.listen(PORT, () => { new SubscriptionServer({ execute, subscribe, schema }, { server: ws, path: '/subscriptions', }); });
  8. Client setup Add support for this transport to Apollo Client

    import { WebSocketLink } from "apollo-link-ws"; import { SubscriptionClient } from "subscriptions-transport-ws"; const GRAPHQL_ENDPOINT = "ws://localhost:3000/graphql"; const client = new SubscriptionClient(GRAPHQL_ENDPOINT, { reconnect: true }); const link = new WebSocketLink(client);
  9. Subscription Component Subscriptions are just listeners, they don’t request any

    data!
 Still need an initial query: const COMMENT_QUERY = gql` query Comment($repoName: String!) { entry(repoFullName: $repoName) { comments { id content } } } `; this.commentsQuery = apollo.watchQuery({ query: COMMENT_QUERY, variables: { repoName: `${params.org}/${params.repoName}` } }); this.comments = this.commentsQuery.valueChanges;
  10. Subscription Component same component ... const COMMENTS_SUBSCRIPTION = gql` subscription

    onCommentAdded( $repoFullName: String!){ commentAdded(repoFullName: $repoFullName){ id content } } `; this.commentsQuery.subscribeToMore({ document: COMMENTS_SUBSCRIPTION, variables: { repoFullName: params.repoFullName, }, updateQuery: (prev, {subscriptionData}) => { if (!subscriptionData.data) { return prev; } return { ...prev, entry: { comments: [ subscriptionData.data.commentAdded, ...prev.entry.comments] } }; } });
  11. Integration with NativeScript You can use Apollo with NativeScript exactly

    as you would with
 normal Angular application.
  12. subZero Software development stack, with the primary focus of building


    GraphQL and REST APIs backed by a PostgreSQL database