Add reactivity to an existing source using GraphQL Mesh

Explore our services and get in touch.
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 ;)