digital-craftsman/self-aware-normalizers

Adds interfaces and normalizers that allow value objects to normalize and denormalize themselves.

v0.2.0 2024-12-05 12:13 UTC

This package is auto-updated.

Last update: 2024-12-05 12:13:36 UTC


README

A Symfony bundle to enable value objects and DTOs to normalize and denormalize themselves through implementing simple interfaces that normalize to scalar values and denormalize themselves from scalar values (string, int, float, bool and array). Adding this kind of logic to the classes themselves might be considered a bad practice, but depending on the use case it will actually be better due to the fact that the data structure and the normalization need to be changed together.

The name implies that the value objects and DTOs are self-aware in the sense that they know how to normalize and denormalize themselves and that they are self-aware enough to do so 🙂

As it's a central part of an application, it's tested thoroughly (including mutation testing).

Latest Stable Version PHP Version Require codecov Packagist Downloads Packagist License

Installation and configuration

Install package through composer:

composer require digital-craftsman/self-aware-normalizers

⚠️ This bundle can be used (and is being used) in production, but hasn't reached version 1.0 yet. Therefore, there will be breaking changes between minor versions. I'd recommend that you require the bundle only with the current minor version like composer require digital-craftsman/self-aware-normalizers:0.2.*. Breaking changes are described in the releases and the changelog. Updates are described in the upgrade guide.

Usage

Normalizers

To make the normalization process easier, there are the following normalizers included:

  • StringNormalizableNormalizer
  • IntNormalizableNormalizer
  • FloatNormalizableNormalizer
  • BoolNormalizableNormalizer
  • ArrayNormalizableNormalizer

Additionally, there is an interface for each of the normalizers. Every class that implements one of the interfaces, will be automatically normalized to the respected type. This means putting the logic of how serialization of a class works within the class. That's not really seen as a good practice. In my experience, the data structure and the normalization need to be changed together. So, I like it better to have both in one place. I've used this approach in multiple large scale projects for years and haven't had a single issue with it yet. But your mileage may vary.

Doctrine types

When using the normalizers, you can also use the same logic for doctrine types. Simply create a new doctrine type extending of one of the following types and register them:

  • StringNormalizableType
  • StringEnumType
  • IntNormalizableType
  • FloatNormalizableType
  • BoolNormalizableType
  • ArrayNormalizableType

As an added bonus, this makes sure, that the structure is always the same no matter if you're using Doctrine to read from the data or a normalizer.

Additional documentation