Add reactivity to an existing source using GraphQL Mesh

This article was published on 2020-12-15 by Jean-Yves Couët @ The Guild Blog

Introduction
Working on the code generator for svelte plugin, I was looking for a public graphQL endpoint having queries, mutations and subscriptions for nice examples.
Unfortunatly I didn't find anything out of the box, ready to use for my demos. So I decided to extend an existing source!
Starting point
Across my researches I found one cool public endpoint regarding SpaceX. It has Queries and Mutations ready to use!
So I decided to pimp this endpoint, and bring a bit of reactivity with subscriptions.
The idea is to publish the new user when it's inserted with this mutation:
mutation addUser {
  insert_users(objects: { name: "jyc" }) {
    affected_rows
    returning {
      name
    }
  }
}
How hard is to do this? Let's find out...

Let's Pimp this graphQL!

Implementation
Multiple ways are possible!
Spoiler alert
Thanks to graphql-mesh, it's dead easy! 🚀🚀🚀
  • Create a new repo
  • mkdir newRepo
    cd newRepo
    yarn init
  • Add graphql-mesh packages
  • yarn add @graphql-mesh/cli @graphql-mesh/graphql @graphql-mesh/transform-resolvers-composition graphql
  • Add .meshrc.yaml file in the root folder with
  • sources:
      - name: spacexGQL
        handler:
          graphql:
            endpoint: https://api.spacex.land/graphql/
    
    additionalTypeDefs: |
      extend type Subscription {
        usersAdded: [users]
      }
    
    transforms:
      - resolversComposition:
          - resolver: 'Mutation.insert_users'
            composer: ./src/composition/insert_user
    
    additionalResolvers:
      - type: Subscription
        field: usersAdded
        pubsubTopic: usersAdded
    Where I
  • declare the graphQL source
  • extend Subscription to listen to user added users
  • compose the existing Mutation.insert_users
  • Add ./src/composition/insert_user.js file with all the logic for this new mutation composition.
  • module.exports = (next) => async (root, args, context, info) => {
      // add returning.id to the selection
      info.operation.selectionSet.selections[0].selectionSet.selections.push({
        kind: 'Field',
        name: {
          kind: 'Name',
          value: 'returning'
        },
        arguments: [],
        directives: [],
        selectionSet: {
          kind: 'SelectionSet',
          selections: [
            {
              kind: 'Field',
              name: {
                kind: 'Name',
                value: 'id'
              },
              arguments: [],
              directives: []
            }
          ]
        }
      })
    
      // send the mutation to the graphQL source
      const result = await next(root, args, context, info)
    
      // select returned ids
      const ids = result.returning.map((c) => c.id)
    
      // Query users enforcing fields to return
      const responseUser = await context.spacexGQL.apiQuery.users(
        {
          where: { id: { _in: ids } }
        },
        {
          fields: {
            id: true,
            name: true,
            rocket: true,
            timestamp: true,
            twitter: true
          }
        }
      )
    
      // publish new users
      context.pubsub.publish('usersAdded', responseUser)
    
      return result
    }
    That's it!
    Wrap up
  • Extending an endpoint with subscription is easy! Thx to tooling.

  • You can find the source on github.

  • You see all this in action directly in the playground

  • I'm now ready to work on the demo for Svelte Codegen! Stay tunned ;)
    Special thanks to n1ru4l who helped me finding the nicest way to do it ;)

    67

    This website collects cookies to deliver better user experience

    Add reactivity to an existing source using GraphQL Mesh