Issue 1:
Let's say this is not a bug report.

Description

A common problem with the serializer and the use of the deserialization is that it will throw errors if a wrong value is inside the given data. This stops any possibility of validation because the deserialization will not end. For information, it is a known issue of ApiPlatform. See api-platform/core#1157, api-platform/core#1735 and api-platform/core#1352.

I suggest adding a new context option that will contain an "error bag". Then we could return the object deserialized and ready for validation with the validation component, as well as a list of errors that occured in the deserialization process.

This way you can return all the validation error properly.

Example

$errors = new ErrorBag();
$myObject = $serializer->deserialize($data, MyObject::class, 'json', ['error_bag' => $errors]);
$contraints = $validator->validate($myObject); // And we're happy here

// Then I can foreach on $errors and $contraints to generate a correct & complete output.

POC

I tried to make this feature (it's a far more simple version than what it should actually be). It's here: https://github.com/Nek-/poc-symfony-deserialization-errors

I can implement this feature if feedbacks are positive.

Issue 2:
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 #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