Open thomasdom opened 5 years ago
Hi! I think that the code responsible for this is https://github.com/api-platform/core/blob/345612c913e1aca6da4f4aa1cd885421ca6385ff/src/JsonApi/Serializer/ErrorNormalizer.php
Feel free to ask for help/open a PR with WIP code !
Solved this using a decorator:
<?php
namespace App\Decorator;
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
final class ApiErrorDecorator implements NormalizerInterface
{
/** @var DenormalizerInterface|NormalizerInterface */
private $decorated;
public function __construct(NormalizerInterface $decorated)
{
if (!$decorated instanceof NormalizerInterface) {
throw new \InvalidArgumentException(sprintf('The decorated normalizer must implement the %s.', NormalizerInterface::class));
}
$this->decorated = $decorated;
}
public function supportsNormalization($data, $format = null)
{
return $this->decorated->supportsNormalization($data, $format);
}
public function normalize($object, $format = null, array $context = [])
{
$error = $this->decorated->normalize($object, $format, $context);
if (!isset($error['links'])) {
$error['links'] = [];
}
$error['links']['about'] = 'https://tools.ietf.org/html/rfc2616#section-10';
if (!isset($error['meta'])) {
$error['meta'] = [];
}
if (isset($error['trace'])) {
$error['meta']['trace'] = $error['trace'];
unset($error['trace']);
}
$error['meta']['class'] = get_class($object);
if ($object instanceof \Symfony\Component\Debug\Exception\FlattenException) {
$error['status'] = $object->getStatusCode();
$error['code'] = $object->getCode();
} else {
$error['code'] = -1;
}
$data = ['errors' => [$error]];
return $data;
}
}
then setting the error format in the api_platform.yml
api_platform:
error_formats:
jsonapi: ['application/vnd.api+json']
and adding the decorator in services.yml
App\Decorator\ApiErrorDecorator:
decorates: 'api_platform.jsonapi.normalizer.error'
arguments: [ '@App\Decorator\ApiErrorDecorator.inner' ]
PHP version: 7.2 Symfony version: 4.3.1 API-Platform version: 2.4.5
How to reproduce
jsonapi
as default payload serializerExample:
Perform a request that will throw an HTTP 400 error due to validation constraint failed
Expected behavior
Error payload respects these following statements (from JSON:API specification on error format and server-side content negotiation):
Example:
Response header
Content-Type
isapplication/vnd.api+json
Actual behavior
Error follows the RFC 7807 HTTP Problem specification, which is not compatible with JSON:API error format specs
Example:
Response header
Content-Type
isapplication/problem+json; charset=utf-8
I would be glad to submit a PR to fix this, but I'm not experienced enough with API Platform Core development. Help from fellow contributors would be very much appreciated :100: