Skip to content

Commit 436921f

Browse files
authored
fix(serializer): json violation list normalizer (#5941)
* fix(serializer): json violation list normalizer fixes #5912 * fixes #5916 * fixes #5916
1 parent 633bde8 commit 436921f

File tree

5 files changed

+127
-1
lines changed

5 files changed

+127
-1
lines changed

features/main/validation.feature

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,3 +157,34 @@ Feature: Using validations groups
157157
]
158158
}
159159
"""
160+
161+
@!mongodb
162+
Scenario: Get violations constraints
163+
When I add "Accept" header equal to "application/json"
164+
And I add "Content-Type" header equal to "application/json"
165+
And I send a "POST" request to "/issue5912s" with body:
166+
"""
167+
{
168+
"title": ""
169+
}
170+
"""
171+
Then the response status code should be 422
172+
And the response should be in JSON
173+
And the JSON should be equal to:
174+
"""
175+
{
176+
"status": 422,
177+
"violations": [
178+
{
179+
"propertyPath": "title",
180+
"message": "This value should not be blank.",
181+
"code": "c1051bb4-d103-4f74-8988-acbcafc7fdc3"
182+
}
183+
],
184+
"detail": "title: This value should not be blank.",
185+
"type": "/validation_errors/c1051bb4-d103-4f74-8988-acbcafc7fdc3",
186+
"title": "An error occurred"
187+
}
188+
"""
189+
And the header "Content-Type" should be equal to "application/problem+json; charset=utf-8"
190+

src/Symfony/Bundle/Resources/config/symfony/validator.xml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,14 @@
3131

3232
<tag name="serializer.normalizer" priority="-800" />
3333
</service>
34+
35+
<service id="api_platform.serializer.normalizer.constraint_violation_list" class="ApiPlatform\Symfony\Validator\Serializer\ConstraintViolationListNormalizer" public="false">
36+
<argument>%api_platform.validator.serialize_payload_fields%</argument>
37+
<argument type="service" id="api_platform.name_converter" on-invalid="ignore" />
38+
39+
<!-- serializer.normalizer.constraint_violation_list is at 915 -->
40+
<tag name="serializer.normalizer" priority="-900" />
41+
</service>
3442
</services>
3543

3644
</container>

src/Symfony/Validator/Exception/ValidationException.php

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
use ApiPlatform\Metadata\Exception\ProblemExceptionInterface;
2020
use ApiPlatform\Metadata\Util\CompositeIdentifierParser;
2121
use ApiPlatform\Validator\Exception\ValidationException as BaseValidationException;
22+
use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
2223
use Symfony\Component\Serializer\Annotation\Groups;
2324
use Symfony\Component\Serializer\Annotation\SerializedName;
2425
use Symfony\Component\Validator\ConstraintViolationListInterface;
@@ -50,7 +51,7 @@
5051
],
5152
graphQlOperations: []
5253
)]
53-
final class ValidationException extends BaseValidationException implements ConstraintViolationListAwareExceptionInterface, \Stringable, ProblemExceptionInterface
54+
final class ValidationException extends BaseValidationException implements ConstraintViolationListAwareExceptionInterface, \Stringable, ProblemExceptionInterface, HttpExceptionInterface
5455
{
5556
private int $status = 422;
5657

@@ -154,4 +155,14 @@ public function __toString(): string
154155

155156
return $message;
156157
}
158+
159+
public function getStatusCode(): int
160+
{
161+
return $this->status;
162+
}
163+
164+
public function getHeaders(): array
165+
{
166+
return [];
167+
}
157168
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the API Platform project.
5+
*
6+
* (c) Kévin Dunglas <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
declare(strict_types=1);
13+
14+
namespace ApiPlatform\Symfony\Validator\Serializer;
15+
16+
use ApiPlatform\Serializer\AbstractConstraintViolationListNormalizer;
17+
use Symfony\Component\Serializer\NameConverter\NameConverterInterface;
18+
19+
/**
20+
* Converts {@see \Symfony\Component\Validator\ConstraintViolationListInterface} the API Problem spec (RFC 7807).
21+
*
22+
* @author Kévin Dunglas <[email protected]>
23+
*/
24+
final class ConstraintViolationListNormalizer extends AbstractConstraintViolationListNormalizer
25+
{
26+
public const FORMAT = 'json';
27+
28+
private array $defaultContext = [];
29+
30+
public function __construct(array $serializePayloadFields = null, NameConverterInterface $nameConverter = null, array $defaultContext = [])
31+
{
32+
parent::__construct($serializePayloadFields, $nameConverter);
33+
34+
$this->defaultContext = array_merge($this->defaultContext, $defaultContext);
35+
}
36+
37+
/**
38+
* {@inheritdoc}
39+
*/
40+
public function normalize(mixed $object, string $format = null, array $context = []): array
41+
{
42+
return $this->getViolations($object);
43+
}
44+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the API Platform project.
5+
*
6+
* (c) Kévin Dunglas <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
declare(strict_types=1);
13+
14+
namespace ApiPlatform\Tests\Fixtures\TestBundle\Entity\Issue5912;
15+
16+
use ApiPlatform\Metadata\ApiResource;
17+
use ApiPlatform\Metadata\NotExposed;
18+
use ApiPlatform\Metadata\Post;
19+
use Symfony\Component\Validator\Constraints\NotBlank;
20+
21+
#[ApiResource(
22+
shortName: 'Issue5912',
23+
operations: [
24+
new NotExposed(),
25+
new Post(),
26+
]
27+
)]
28+
class Dummy
29+
{
30+
#[NotBlank]
31+
public string $title;
32+
}

0 commit comments

Comments
 (0)