Skip to content

Commit 0c07a44

Browse files
authored
docs(mutations): Document responses (#1037)
1 parent 62c9a84 commit 0c07a44

25 files changed

Lines changed: 766 additions & 110 deletions

doc/SUMMARY.md

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,28 +2,29 @@
22

33
## Getting started
44

5-
* [Installation](starting/README.md)
6-
* [Custom schemas](starting/custom-schema.md)
5+
- [Installation](starting/README.md)
6+
- [Creating schemas](starting/custom-schema.md)
77

88
## Data Producers
99

10-
* [Data Producers](producers/README.md)
11-
* [Built-in producers](producers/built-in.md)
12-
* [Custom producers](producers/custom.md)
13-
* [Composing producers](producers/composing.md)
10+
- [Data Producers](producers/README.md)
11+
- [Built-in producers](producers/built-in.md)
12+
- [Custom producers](producers/custom.md)
13+
- [Composing producers](producers/composing.md)
1414

1515
## Queries
1616

17-
* [Queries](queries/README.md)
18-
* [Nodes](queries/nodes.md)
19-
* [Entity references](queries/references.md)
20-
* [Menus](queries/menus.md)
21-
* [Routes](queries/routes.md)
17+
- [Queries](queries/README.md)
18+
- [Nodes](queries/nodes.md)
19+
- [Entity references](queries/references.md)
20+
- [Menus](queries/menus.md)
21+
- [Routes](queries/routes.md)
2222

2323
## Mutations
2424

25-
* [Mutations](mutations/README.md)
25+
- [Mutations](mutations/README.md)
26+
- [Validations](mutations/validations.md)
2627

2728
## Advanced
2829

29-
* [Composable schemas](advanced/composable-schemas.md)
30+
- [Composable schemas](advanced/composable-schemas.md)

doc/mutations/README.md

Lines changed: 49 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,43 @@
11
# Mutations
22

3-
In version 4 of Drupal GraphQL `Mutations` work a lot more similar to queries than they do in 3.x. Mutations are also technically Data producers which we already looked at.
3+
In version 4 of Drupal GraphQL `Mutations` work a lot more similar to queries than they do in 3.x. Mutations are called using also Data producers which we already looked at.
44

5-
Lets create a mutation that creates a new article. In this case it takes a data parameter that can have a `title` and a `creator` in order to set these fields when creating the new article if they have been provided.
5+
Let's make a mutation that creates a new article. In this case it takes a data parameter that can have a `title` and a `description` in order to set these fields when creating the new article if they have been provided.
66

77
Similar to queries we can start by adding the necessary schema information, not only to register our new mutation but also provide type safety on all parameters as well. This mutation will return the newly created "Article".
88

9-
The code with all the demo queries and mutations in these docs can be found in [this repository](https://github.com/joaogarin/mydrupalgql).
9+
The code with all the demo queries and mutations in these docs can be found in the same `graphql_composable` example module.
1010

1111
## Add the schema declaration
1212

13-
```
14-
schema {
15-
mutation: Mutation
16-
}
13+
Adapt your base schema file to something like this where we include a new type called `Mutation` and we also create a new input called `ArticleInput` which we will use as the type for our mutation argument.
1714

18-
type Mutation {
19-
createArticle(data: ArticleInput): Article
20-
}
15+
```
16+
type Mutation
2117
22-
type Article implements NodeInterface {
23-
id: Int!
24-
title: String!
25-
creator: String
26-
}
18+
scalar Violation
2719
28-
interface NodeInterface {
29-
id: Int!
20+
type Article {
21+
id: Int!
22+
title: String!
23+
author: String
3024
}
3125
3226
input ArticleInput {
33-
title: String!
34-
description: String
27+
title: String!
28+
description: String
3529
}
30+
```
31+
32+
And now in our `.exntends.graphqls` file we will extend the Mutation type to add our new mutation. This is so that in the future other modules can also themselves extend this type with new mutations keeping things organized.
3633

34+
```
35+
extend type Mutation {
36+
createArticle(data: ArticleInput): Article
37+
}
3738
```
3839

39-
We can now see we have a Mutation called `createArticle` which takes a data parameter, but because GraphQL is heavily typed we know everything we can and must include in the new Article like the title which is mandatory in this case.
40+
We can now see we have a Mutation called `createArticle` which takes a data parameter, and because GraphQL is heavily typed we know everything we can and must include in the new Article (`ArticleInput`) like the title which is mandatory in this case.
4041

4142
## Implement the custom data producer (mutation)
4243

@@ -45,7 +46,7 @@ We now need to implement the actual mutation, in the file `src/Plugin/GraphQL/Da
4546
```php
4647
<?php
4748

48-
namespace Drupal\mydrupalgql\Plugin\GraphQL\DataProducer;
49+
namespace Drupal\graphql_composable\Plugin\GraphQL\DataProducer;
4950

5051
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
5152
use Drupal\Core\Session\AccountInterface;
@@ -110,42 +111,48 @@ class CreateArticle extends DataProducerPluginBase implements ContainerFactoryPl
110111

111112
/**
112113
* Creates an article.
113-
*
114+
*
114115
* @param array $data
115116
* The title of the job.
116117
*
117-
* @return \Drupal\node\NodeInterface
118+
* @return \Drupal\Core\Entity\EntityBase|\Drupal\Core\Entity\EntityInterface
118119
* The newly created article.
119120
*
120121
* @throws \Exception
121122
*/
122123
public function resolve(array $data) {
123124
if ($this->currentUser->hasPermission("create article content")) {
124-
$values = [
125-
'title' => $data['title'],
126-
'field_article_creator' => $data['creator'],
127-
];
128-
$node = Node::create($values);
129-
$node->save();
130-
return $node;
125+
$values = [
126+
'type' => 'article',
127+
'title' => $data['title'],
128+
'body' => $data['description'],
129+
];
130+
$node = Node::create($values);
131+
$node->save();
132+
return $node;
131133
}
132134
return NULL;
133135
}
134136

135137
}
136-
137138
```
138139

139-
## Adding resolvers
140+
### Important note
141+
142+
One thing to notice when creating mutations like this is that Access checking needs to be done in the mutation, for queries this usually is done in the
143+
data producer directly (e.g. `entity_load` has access checking built-in) but because we are programatically creating
144+
things we need to check the user actually has access to do the operation.
145+
146+
## Calling the mutation
140147

141-
To add the resolvers we go to our schema implementation and call the created data producer `create_article` inside the `getResolverRegistry` method.
148+
To add the resolvers for the `createArticle` mutation we go to our schema implementation and call the created data producer `create_article` inside the `registerResolvers` method.
142149

143150
```php
144151
/**
145152
* {@inheritdoc}
146153
*/
147-
protected function getResolverRegistry() {
148-
154+
public function registerResolvers(ResolverRegistryInterface $registry) {
155+
149156
...
150157
// Create article mutation.
151158
$registry->addFieldResolver('Mutation', 'createArticle',
@@ -159,10 +166,10 @@ protected function getResolverRegistry() {
159166
```
160167

161168
This mutation can now be called like this :
162-
169+
163170
```graphql
164171
mutation {
165-
createArticle(data: {title: "Hello GraphQl 2"}) {
172+
createArticle(data: { title: "Hello GraphQl 2" }) {
166173
... on Article {
167174
id
168175
title
@@ -171,7 +178,7 @@ mutation {
171178
}
172179
```
173180

174-
and should return something like :
181+
and should return something like :
175182

176183
```json
177184
{
@@ -183,3 +190,7 @@ and should return something like :
183190
}
184191
}
185192
```
193+
194+
## Validating mutations
195+
196+
Now that we have our mutation in place one way we can improve this is by adding some validation so that if someone is not to create an article they get a nice error back (technically in Drupal these are called Violations) so that it can be printed to the user in whichever app this is called. In the next chapter we will look at how we can improve this code to add some validation to it.

0 commit comments

Comments
 (0)