Skip to content

Commit f3a54a2

Browse files
authored
fix: json formatted resource should not get xml errors #7287 (#7297)
1 parent 2cde062 commit f3a54a2

File tree

6 files changed

+131
-2
lines changed

6 files changed

+131
-2
lines changed

src/State/ApiResource/Error.php

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@
3838
routeName: '_api_errors',
3939
outputFormats: [
4040
'json' => ['application/problem+json', 'application/json'],
41-
'xml' => ['application/xml', 'text/xml'],
4241
],
4342
hideHydraOperation: true,
4443
normalizationContext: [
@@ -75,6 +74,21 @@
7574
'ignored_attributes' => ['trace', 'file', 'line', 'code', 'message', 'traceAsString', 'previous'],
7675
],
7776
),
77+
new Operation(
78+
errors: [],
79+
name: '_api_errors_xml',
80+
routeName: '_api_errors',
81+
outputFormats: [
82+
'xml' => ['application/xml', 'text/xml'],
83+
],
84+
hideHydraOperation: true,
85+
normalizationContext: [
86+
SchemaFactory::OPENAPI_DEFINITION_NAME => '',
87+
'groups' => ['jsonproblem'],
88+
'skip_null_values' => true,
89+
'ignored_attributes' => ['trace', 'file', 'line', 'code', 'message', 'traceAsString', 'previous'],
90+
],
91+
),
7892
new Operation(
7993
name: '_api_errors',
8094
hideHydraOperation: true,

src/Symfony/EventListener/ErrorListener.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,7 @@ private function getFormatOperation(?string $format): string
202202
'jsonproblem' => '_api_errors_problem',
203203
'jsonld' => '_api_errors_hydra',
204204
'jsonapi' => '_api_errors_jsonapi',
205+
'xml' => '_api_errors_xml',
205206
'html' => '_api_errors_problem', // This will be intercepted by the SwaggerUiProvider
206207
default => '_api_errors_problem',
207208
};

src/Validator/Exception/ValidationException.php

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@
5151
name: '_api_validation_errors_problem',
5252
outputFormats: [
5353
'json' => ['application/problem+json'],
54-
'xml' => ['application/xml', 'text/xml'],
5554
],
5655
normalizationContext: [
5756
'groups' => ['json'],
@@ -79,6 +78,17 @@
7978
'ignored_attributes' => ['trace', 'file', 'line', 'code', 'message', 'traceAsString', 'previous'],
8079
]
8180
),
81+
new ErrorOperation(
82+
name: '_api_validation_errors_xml',
83+
outputFormats: [
84+
'xml' => ['application/xml', 'text/xml'],
85+
],
86+
normalizationContext: [
87+
'groups' => ['json'],
88+
'ignored_attributes' => ['trace', 'file', 'line', 'code', 'message', 'traceAsString', 'previous'],
89+
'skip_null_values' => true,
90+
]
91+
),
8292
],
8393
graphQlOperations: []
8494
)]
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
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\ApiResource\Issue7287;
15+
16+
use ApiPlatform\Metadata\ApiResource;
17+
use ApiPlatform\Metadata\GetCollection;
18+
use ApiPlatform\Metadata\NotExposed;
19+
20+
#[ApiResource(
21+
outputFormats: ['jsonld'],
22+
operations: [
23+
new GetCollection(provider: [self::class, 'provide']),
24+
new NotExposed(uriVariables: ['id']),
25+
]
26+
)]
27+
class OperationWithDefaultFormat
28+
{
29+
public function __construct(
30+
public string $id,
31+
) {
32+
}
33+
34+
public static function provide(): array
35+
{
36+
return [new self('1')];
37+
}
38+
}

tests/Fixtures/app/config/config_common.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ api_platform:
5858
jsonld: ['application/ld+json']
5959
jsonapi: ['application/vnd.api+json']
6060
html: ['text/html']
61+
xml: ['application/xml', 'text/xml']
6162
graphql:
6263
enabled: true
6364
nesting_separator: __

tests/Functional/ErrorFormatTest.php

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
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\Functional;
15+
16+
use ApiPlatform\Symfony\Bundle\Test\ApiTestCase;
17+
use ApiPlatform\Tests\Fixtures\TestBundle\ApiResource\Issue7287\OperationWithDefaultFormat;
18+
use ApiPlatform\Tests\SetupClassResourcesTrait;
19+
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
20+
use Symfony\Component\DependencyInjection\ContainerBuilder;
21+
22+
class ErrorFormatAppKernel extends \AppKernel
23+
{
24+
protected function build(ContainerBuilder $container): void
25+
{
26+
parent::build($container);
27+
$container->addCompilerPass(new class implements CompilerPassInterface {
28+
public function process(ContainerBuilder $container): void
29+
{
30+
$def = $container->getDefinition('api_platform.error_listener');
31+
$def->setArgument(5, ['jsonld' => ['application/ld+json']]);
32+
}
33+
});
34+
}
35+
}
36+
37+
final class ErrorFormatTest extends ApiTestCase
38+
{
39+
use SetupClassResourcesTrait;
40+
41+
protected static function getKernelClass(): string
42+
{
43+
return ErrorFormatAppKernel::class;
44+
}
45+
46+
protected static ?bool $alwaysBootKernel = true;
47+
48+
/**
49+
* @return class-string[]
50+
*/
51+
public static function getResources(): array
52+
{
53+
return [OperationWithDefaultFormat::class];
54+
}
55+
56+
public function testNotAcceptableXml(): void
57+
{
58+
self::createClient()->request('GET', '/operation_with_default_formats', [
59+
'headers' => ['accept' => 'text/xml'],
60+
]);
61+
62+
$this->assertJsonContains(['detail' => 'Requested format "text/xml" is not supported. Supported MIME types are "application/ld+json".']);
63+
$this->assertResponseStatusCodeSame(406);
64+
}
65+
}

0 commit comments

Comments
 (0)