Creating mutation plugins
The graphql module uses the Drupal plugin system for a lot of the extensibility features of plugins. So a lot of the times when you want to extend the graphql module (for example when creating your own mutations) you will be using the plugin system and creating your own plugins.
Why the automatic mutations were removed.
In this article it's well explained why automatic mutations were removed. But this, as stated in the article, does not mean that creating mutations is complicated. In fact, it's a simple task and one that might even provide with the extra flexibility you know and love from Drupal.
Mutations to create Drupal Entities
One of the most common things you will want to do when with mutations is to create, update and delete entities. These CRUD operations on entities were made as simple as possible to implement and only require you to extend some generic classes provided by the graphql_core module.
So let's have a look at how you can create a mutation from scratch to generate a new entity of type node, and in this case a new article. You can refer to the Examples repository to look at some other examples as well for how to create other kinds of mutations.
CreateArticle Plugin
The first step to create a mutation is to make the plugin. The graphql module provides a base class for creating new entities called CreateEntityBase
. You should implement a plugin that extends this class when you want to create an entity.
Let's look at what the code for this plugin looks like :
We can see a couple things in this code that are particularly interesting :
Namespacing and folder structure
The first thing we need to do when implementing the plugin is to give it a namespace, in this case we can see we use graphql_examples
, you should replace this by your own module name.
Make sure that this plugin lives inside {{module_name}}//src/Plugin/GraphQL
GraphQLMutation annotations
The graphql module uses anotations for classes in order to have some information define the mutation in a simple way, things like :
id - The id of the mutation.
entity_type - The type of entity that is going to be created from this mutation (only important for when extending CreateEntityBase mutations)
entity_bundle - The bundle of the entity that is going to be created
secure - Fields that are not marked secure are automatically blocked in untrusted environments. For example there is a field that allows to fetch content from a remote url, which would basically turn your website into a proxy for anybody. This field will only work with a certain user permission or in persisted queries, where we are in control of what they do. The other way around, a field that is marked as secure doesn't allow any operations drupal itself wouldn't.
name - The name for the mutation. This name is what you will use when calling the mutation.
type - the "type" is the returned type by the mutation. In the example above the mutation returns a "EntityCrudOutput" type which is provided by the graphql module itself.
arguments - The arguments passed to the mutation. These are the fields for the entity you want to create, in the case above we are passing one argument called "Input" of type "ArticleInput". We will look at InputTypes afterwards. But essentially since graphql is strictly typed we want to provide information for types for each field we pass to the mutation we can do that using "InputTypes".
extractEntityInput method
There is one method you should always implement when doing mutations, that is the extractEntityInput
method which will be sort of a mapping between the arguments you pass to the mutation and the fields that drupal expects to receive for the entity being created.
We can see we are assigning the title
that we are passing in the input (we will look at the ArticleInput after) to the title property in the entity, same for the body
.
Mutations to update Drupal Entities
Let's continue with our article example. In this case we implement a mutation to update a given article. Because we are updating a particular entity and we need to know which entity it is, we will need to provide the plugin annotation with something extra, an Id for the entity.
The first thing we noticed is we are now using UpdateEntityBase
instead of "CreateEntityBase" as our parent class, we can also see that we use the same argument "Input" as above but we also have another argument called id
. The Graphql Module will be smart enough to use that id to match to the right entity.
Mutations to Delete Drupal Entities
The only thing left now is really to delete the entity right? This is the simplest type of operation out of the 3, because we only need to give graphql the id
, it will check if we can access that type of operation and if so delete the entity with the id we give to it. So let's look at how the plugin looks like
We extend the DeleteEntityBase
class and only require one argument: the id of the entity we want to delete. Additionally we add the required annotations as we previously did for the other mutations.
ArticleInput
We know from the examples above that we need to define the arguments for mutations. Similar to how a function, mutations receive arguments that can be used to do whatever the mutation needs to do to work. In order for graphql to know information about the arguments we create an InputType
. The ArticleInput that we used above looks like this :
We can see again that we namespace this plugin to our module name, in this case graphql_examples
should be replaced by your own module name. This file should live inside {{module_name}}/src/Plugin/GraphQL/InputTypes/ArticleInput.php
We can also see above that we only use annotations here to define the arguments inside the fields
property. So we know that it receives a title
and that's a "String" and we also receive a body
which is also a String
.
Last updated