GraphQL with Sinatra (Ruby) — Part 2— Mutations

Honeycomb Facade — Photo by chuttersnap on Unsplash

In this post let’s see how to create GraphQL mutations to add a speaker to our database.

In Part 1 of this series talks about how to set things up, and how to define a query to get a list of Speakers from our Conference GraphQL API.


A mutation is something that mutates or changes the data in the server. In DB terms, if we need to change the data in a table using graphql we need mutations — be it an INSERT, UPDATE or DELETE. Only SELECTs are covered with a Query.

Note: Updated to the new class-based API, which was introduced in version 1.8 of the gem. While the define DSL based syntax will still work, it will eventually get removed in version 2.0.

So to add a new speaker to the database we need a mutation.

Adding data to the application via Mutations

In the GraphQL language, a mutation is of the form

mutation AddSpeaker($name:String, $talkTitle:String) {
createSpeaker(name: $name, talkTitle:$talkTitle) {
success
errors
}
}

A set of “query” variables needs to be supplied to the GraphQL endpoint.
Say for example,


{
"name": "John Doe",
"talkTitle": "Introduction to GraphQL in Ruby"
}

Read more about GraphQL mutations and its syntax in the specifications — https://graphql.org/learn/queries/#mutations

For our little server to accept mutations, we need to make some changes and add more files for defining mutations. Lets see how, step-by-step.

STEP 5: Adding a Mutation root type

A mutation root MutationType has to be created and it should then be added to our Schema, like the QueryType that was added in the last post.

STEP 6: Define a Mutation for speaker creation

Next, we need to tell GraphQL about the parameters that needs to be accepted for creating a new speaker.

Let’s split this into a separate file, that handles this mutation — create_speaker.rb. Instead of inheriting from GraphQL::Schema::Mutation we create a mutation base class Mutations::BaseMutation. Also lets group all the mutations in mutations folder.

It needs to accept all the fields for a speaker, which we created as strings in the DB. In GraphQL ruby, strings are represented with the String type, as defined in the gem.

Next we need to take these fields and then call speaker.save with the defined input fields in the resolve function.

This returns a hash with success and errors. We need to tell GraphQL about it as well. Note: errors is an array of Strings. We define these as fields in the mutation.

Now the CreateSpeaker mutation is complete. It needs to be added to the root mutation — MutationType so that it gets included in the schema.

Restart the server with bundle exec puma.

If you use a client like GraphiQL, you should be able to see the docs in the right sidebar changes and now has a Mutation.

Add a new speaker, with the mutation and the query variables in the client.

Execute the mutation in the GraphiQL client. You should be able to see the response data json, with something like below:

Successful mutation execution — GraphiQL client

The CreateSpeaker mutation has all the fields optional, but the Speaker model validates the presence of the name field. If you try to create a speaker without giving a name field, it will show up in errors return field.

We can avoid this validation at the schema level, by making the required argument mandatory. You just need to change null: false to the respective arguments.

Now the name and talk_title fields are non-nullable fields, and you’ll have to always give these fields when executing the mutation. Read about the type system in the official documentation.

Show me the code

You can see all the code for this post in the sinatra-graphql Github repository.


If you found this article useful, please click on the 👏 button a few times to make others find the article and show your support!
Don’t forget to follow me, to get notified of upcoming articles like these.