Skip to content

Commit 4b7ddd0

Browse files
authored
fix(graphql): no validate on delete mutation (#6388)
* fix(graphql): validate before resolver, no validate on delete fixes #6370 * use interface instead * Revert "fix(graphql): resolver before validation" This reverts commit b10c7c8. * add note to changelog
1 parent 3fb7231 commit 4b7ddd0

File tree

7 files changed

+34
-51
lines changed

7 files changed

+34
-51
lines changed

CHANGELOG.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ if (null === $operation->canDeserialize()) {
3838

3939
Previously listeners did the checks before reading our flags and you could not force the values.
4040

41+
When using GraphQl, with `event_listeners_backward_compatibility_layer: true`, mutation resolver gets called before validation, when using `false` (the future default) validation occurs on the user's input.
42+
4143
## v3.3.1 (pre-release)
4244

4345
### Bug fixes
@@ -466,6 +468,13 @@ Listeners will not get removed in API Platform 4 but will rather use our new Pro
466468
#[Post(read: true)] // to force reading even though it's a POST
467469
```
468470

471+
- `ApiPlatform\Api` got moved to `ApiPlatform\Metadata`
472+
473+
- Adds `assertMercureUpdateMatchesJsonSchema(Update $update, array $topics, array|object|string $jsonSchema = '', bool $private = false, string $id = null, string $type = null, int $retry = null, string $message = '')`
474+
- The handle links feature is experimental
475+
476+
When using GraphQl, with `event_listeners_backward_compatibility_layer: true`, mutation resolver gets called before validation, when using `false` (the future default) validation occurs on the user's input.
477+
469478
## v3.2.0-beta.2
470479

471480
### Bug fixes

features/graphql/mutation.feature

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1036,18 +1036,19 @@ Feature: GraphQL mutation support
10361036
And the JSON node "data.uploadMultipleMediaObject.mediaObject.contentUrl" should be equal to "test.gif"
10371037

10381038
@!mongodb
1039-
Scenario: Mutation should run before validation
1039+
Scenario: Delete an invalid item through a mutation
10401040
When I send the following GraphQL request:
10411041
"""
10421042
mutation {
1043-
createActivityLog(input: {name: ""}) {
1043+
deleteActivityLog(input: {id: "/activity_logs/1"}) {
10441044
activityLog {
1045-
name
1045+
id
10461046
}
10471047
}
10481048
}
10491049
"""
10501050
Then the response status code should be 200
10511051
And the response should be in JSON
10521052
And the header "Content-Type" should be equal to "application/json"
1053-
And the JSON node "data.createActivityLog.activityLog.name" should be equal to "hi"
1053+
And the JSON node "errors" should not exist
1054+
And the JSON node "data.deleteActivityLog.activityLog" should exist

src/GraphQl/Resolver/Factory/ResolverFactory.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
namespace ApiPlatform\GraphQl\Resolver\Factory;
1515

1616
use ApiPlatform\GraphQl\State\Provider\NoopProvider;
17+
use ApiPlatform\Metadata\DeleteOperationInterface;
1718
use ApiPlatform\Metadata\GraphQl\Mutation;
1819
use ApiPlatform\Metadata\GraphQl\Operation;
1920
use ApiPlatform\Metadata\GraphQl\Query;
@@ -75,7 +76,7 @@ private function resolve(?array $source, array $args, ResolveInfo $info, ?string
7576
$context = ['source' => $source, 'args' => $args, 'info' => $info, 'root_class' => $rootClass, 'graphql_context' => &$graphQlContext];
7677

7778
if (null === $operation->canValidate()) {
78-
$operation = $operation->withValidate($operation instanceof Mutation);
79+
$operation = $operation->withValidate($operation instanceof Mutation && !$operation instanceof DeleteOperationInterface);
7980
}
8081

8182
$body ??= $this->provider->provide($operation, [], $context);

src/Symfony/Bundle/Resources/config/graphql.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -158,8 +158,8 @@
158158
<argument type="tagged_locator" tag="api_platform.parameter_provider" index-by="key" />
159159
</service>
160160

161-
<!-- Validation occurs at 200, we want validation to be after we reach custom resolvers -->
162-
<service id="api_platform.graphql.state_provider.resolver" class="ApiPlatform\GraphQl\State\Provider\ResolverProvider" decorates="api_platform.graphql.state_provider" decoration-priority="220">
161+
<!-- Validation occurs at 200, we want validation to be over when we reach custom resolvers -->
162+
<service id="api_platform.graphql.state_provider.resolver" class="ApiPlatform\GraphQl\State\Provider\ResolverProvider" decorates="api_platform.graphql.state_provider" decoration-priority="190">
163163
<argument type="service" id="api_platform.graphql.state_provider.resolver.inner" />
164164
<argument type="service" id="api_platform.graphql.resolver_locator" />
165165
</service>

tests/Fixtures/TestBundle/ApiResource/Issue6354/ActivityLog.php

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,20 +14,31 @@
1414
namespace ApiPlatform\Tests\Fixtures\TestBundle\ApiResource\Issue6354;
1515

1616
use ApiPlatform\Metadata\ApiResource;
17-
use ApiPlatform\Metadata\GraphQl\Mutation;
17+
use ApiPlatform\Metadata\Get;
18+
use ApiPlatform\Metadata\GraphQl\DeleteMutation;
19+
use ApiPlatform\Metadata\Operation;
1820
use Symfony\Component\Validator\Constraints\NotBlank;
1921

2022
#[ApiResource(
23+
operations: [
24+
new Get(
25+
provider: [self::class, 'provide']
26+
),
27+
],
2128
graphQlOperations: [
22-
new Mutation(
23-
resolver: 'app.graphql.mutation_resolver.activity_log',
24-
name: 'create'
29+
new DeleteMutation(
30+
name: 'delete'
2531
),
2632
]
2733
)]
2834
class ActivityLog
2935
{
30-
public function __construct(#[NotBlank()] public ?string $name = null)
36+
public function __construct(public ?int $id = null, #[NotBlank()] public ?string $name = null)
37+
{
38+
}
39+
40+
public static function provide(Operation $operation, array $uriVariables = [], array $context = []): object|array|null
3141
{
42+
return new self(1);
3243
}
3344
}

tests/Fixtures/TestBundle/ApiResource/Issue6354/CreateActivityLogResolver.php

Lines changed: 0 additions & 34 deletions
This file was deleted.

tests/Fixtures/app/config/config_common.yml

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -455,8 +455,3 @@ services:
455455
tags:
456456
- name: 'api_platform.parameter_provider'
457457
key: 'ApiPlatform\Tests\Fixtures\TestBundle\Parameter\CustomGroupParameterProvider'
458-
459-
app.graphql.mutation_resolver.activity_log:
460-
class: 'ApiPlatform\Tests\Fixtures\TestBundle\ApiResource\Issue6354\CreateActivityLogResolver'
461-
tags:
462-
- name: 'api_platform.graphql.resolver'

0 commit comments

Comments
 (0)