-
Notifications
You must be signed in to change notification settings - Fork 3
IBX-9678: JsonSerializableNormalizer return type mismatch causing 500 error #160
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe it's an overkill but it would be great to have an integration test with a bit more complicated case, like object that uses MoneyObjecy
, please see https://github.com/ibexa/rest/blob/main/tests/integration/Serializer/SerializerTest.php
Maybe you could add another case there and use TestDataObject
with MoneyObject
.
|
||
namespace Ibexa\Tests\Rest\Output; | ||
|
||
class MoneyObject implements \JsonSerializable |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
class MoneyObject implements \JsonSerializable | |
final class MoneyObject implements \JsonSerializable |
* @copyright Copyright (C) Ibexa AS. All rights reserved. | ||
* @license For full copyright and license information view LICENSE file distributed with this source code. | ||
*/ | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
declare(strict_types=1); | |
use Ibexa\Tests\Rest\Output\MoneyObject; | ||
use PHPUnit\Framework\TestCase; | ||
|
||
class ArrayNormalizerTest extends TestCase |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
class ArrayNormalizerTest extends TestCase | |
final class ArrayNormalizerTest extends TestCase |
/** | ||
* @copyright Copyright (C) Ibexa AS. All rights reserved. | ||
* @license For full copyright and license information view LICENSE file distributed with this source code. | ||
*/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
*/ | |
*/ | |
declare(strict_types=1); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To be honest, whole JsonSerializableNormalizer
class can be removed, as Symfony\Component\Serializer\Normalizer\JsonSerializableNormalizer
already exists.
☝️ all we need to take care is to properly register this as a service (under a non-class id, with class
declared, if using YAML service files) to the correct serializers.
#[\ReturnTypeWillChange] | ||
public function jsonSerialize() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can narrow down the return type from an interface. This is allowed.
#[\ReturnTypeWillChange] | |
public function jsonSerialize() | |
/** | |
* @return array<mixed> | |
*/ | |
public function jsonSerialize(): array |
* {@inheritDoc} | ||
*/ | ||
public function normalize($object, ?string $format = null, array $context = []): string | ||
public function normalize($object, ?string $format = null, array $context = []): string|array |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, we should remove the return type, as \JsonSerializable::jsonSerialize() method does not offer any guaranties about the returned type 😞
public function normalize($object, ?string $format = null, array $context = []): string|array | |
public function normalize($object, ?string $format = null, array $context = []) |
Description:
JsonSerializableNormalizer is hint typed to return string but we also normalize objects like
Money/Money
that return an array. If we try to create an order through API on latest Ibexa 5.0 the order would get created but on the return we would get an 500 error. I have changed the hint type to cover array as well.I have also added a test to cover this scenario. Rest package doest not uses
moneyphp/money
package anywhere directly so instead of adding a dependency I have created a dummy object with minimal implementation to simulate the behavior of real Money object that returns an array.Discovered while testing https://github.com/ibexa/order-management/pull/137 on 5.0
For QA:
Documentation: