Add reactivity to an existing source using GraphQL Mesh

Jean-Yves Couët

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. Unfortunately 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! 🚀🚀🚀

1. Create a New Repo

mkdir newRepo
cd newRepo
yarn init

2. Add graphql-mesh Packages

yarn add @graphql-mesh/cli @graphql-mesh/graphql @graphql-mesh/transform-resolvers-composition graphql

3. Add .meshrc.yaml File in the Root Folder With

.meshrc.yaml
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

4. Add ./src/composition/insert_user.js File with All the Logic for This New Mutation Composition

insert_user.js
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 ;)

@jycouet

💡

Special thanks to n1ru4l who helped me find the nicest way to do it ;)

Join our newsletter

Want to hear from us when there's something new?
Sign up and stay up to date!

*By subscribing, you agree with Beehiiv’s Terms of Service and Privacy Policy.