Class-based Group Attributes
Serialization groups allow to serialize different sets of attributes from your entities according to your needs. A group name is an arbitrary string that associates a property to one or more of those serialization sets.
In Symfony 6.4 we're improving serialization groups so you can also define them at class level. This will associate all properties to that group, in addition to the groups that each property optionally associates to:
1 2 3 4 5 6 7 8 9 10 11 12 13
#[ORM\Entity]
#[Groups(['show_product'])]
class Product
{
// ...
#[ORM\Column(type: 'string', length: 255)]
#[Groups(['list_product'])]
private string $name;
#[ORM\Column(type: 'text')]
private string $description;
}
In this example, the name
property belongs to show_product
and list_product
groups, but the description
property only belongs to the show_product
group.
Translatable Objects Normalizer
In Symfony 5.2 we introduced translatable objects, which are objects that contain all the information needed to translate its own contents, such as the translation parameters and the translation domain.
In Symfony 6.4, we're introducing a TranslatableObject normalizer, which
translates the contents of these objects to the locale defined in the NORMALIZATION_LOCALE_KEY
option when serializing objects. There's nothing to do to use this new normalizer.
Upgrade your application to Symfony 6.4 or higher and this will work out-of-the-box.
Validation Groups Provider Outside DTOs
Currently, you can determine the sequence of groups to apply dynamically based
on the state of your DTO by implementing the GroupSequenceProviderInterface
in your DTO class:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
use Symfony\Component\Validator\GroupSequenceProviderInterface;
#[Assert\GroupSequenceProvider]
class UserDto implements GroupSequenceProviderInterface
{
// ...
public function getGroupSequence(): array|GroupSequence
{
if ($this->isCompanyType()) {
return ['User', 'Company'];
}
return ['User'];
}
}
However, in more advanced cases you might need to use a service to define that group sequence. A possible solution would be to inject the service in the DTO constructor, but that's usually out of the scope of the DTO responsibility (and, strictly speaking, could not fit the SOLID principles).
In Symfony 6.4 we're improving this by allowing you to create a class that
implements the GroupProviderInterface
and then use it in your DTO via the
GroupSequenceProvider
attribute:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
use Symfony\Component\Validator\Constraints as Assert;
#[Assert\GroupSequenceProvider(provider: UserGroupProvider::class)]
class UserDto
{
// ...
}
use Symfony\Component\Validator\Constraints\GroupSequence;
use Symfony\Component\Validator\GroupProviderInterface;
class UserGroupProvider implements GroupProviderInterface
{
public __constructor(private readonly ConfigService $config)
{
}
public function getGroups(object $object): array|GroupSequence
{
if ($this->config->isEnabled()) {
return ['User', $this->config->getGroup()];
}
return ['User'];
}
}
Detailed JSON Decoding Errors
Consider the following JSON snippet which contains a certain syntax error:
1
$jsonContent = "{'foo': 'bar'}";
In current Symfony versions, when trying to deserialize that content, you'll see this error:
1 2 3 4
{
"title": "Deserialization Failed",
"detail": "Syntax error"
}
Not very useful, right? In Symfony 6.4 we're improving this significantly. First, install the seld/jsonlint dependency in your project. Then, upgrade to Symfony 6.4 or higher and, when the application runs in the debug mode, you'll see detailed errors like the following:
1 2 3 4
{
"title": "Deserialization Failed",
"detail": "Parse error on line 1: {'foo': 'bar'} Invalid string, it appears you used single quotes instead of double quotes"
}
Great ! Thank you