-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
Description
Description
Add a way to make the Serializer try its best to continue denormalization to the end and collect all failures instead of stopping and throwing an exception at first failure. If anything goes wrong, the thrown exception provides all collected failures, similarly to what the Validator does.
Example
When working on an application that exposes an API (with e.g. API Platform) and uses Value Objects to represent data, a way to process a request payload can be as follows:
- Have a Data Transfer Object class that represents the payload with basic types (
int
,string
, ...) - Use the Serializer to convert the payload into an instance of that DTO class
- Use the Validator to assert that all values in the DTO are valid
- In case it's not valid, expose the violations to the client in a 400 response
- Otherwise, pass the DTO to other parts of the application, converting all basic values into Value Objects as needed.
I see several drawbacks though:
- most validation rules are written twice: in the Value Objects and in the Validator mapping
- it is not really type safe: a method that is passed the DTO has no guarantee that it is indeed valid (maybe it was not actually validated or it was mutated afterwards).
A possible solution I imagine is to have the Serializer denormalize the values using Value Objects directly instead of basic types. This should only require having a denormalizer for all involved objects to work. This would solve issues mentioned above but would bring another one: since current implementation of the denormalization process stops and throws an exception as soon as it fails denormalizing a single value, the API would not be able to report all violations in the payload anymore: instead it would only report the single value whose denormalization failed.
With the proposed feature, the new implementation to process a request payload would be:
- Have a Data Transfer Object that represents the payload with Value Objects and uses a constructor instead of public properties (leveraging [Serializer] Instantiator - Add an interface and default implementation to instantiate objects #30956 maybe)
- Use the Serializer to convert the payload into an instance of that DTO class
- In case of denormalization failures, expose them to the client in a 400 response
- Otherwise, pass the DTO to other parts of the application without any further processing