Proposal on "disable_type_enforcement" on the normalizer !
See original GitHub issueHello everyone, since I never did a pull request anywhere and also since I really don’t know if the code I made will enhance ApiPlatform or harm it, I put it in the issues section !
This reflexion comes after the issue https://github.com/api-platform/api-platform/issues/788 about the fact that data was validated AFTER the deserialization process which leads to sometimes having an error from Doctrine Type Validation and the Validation Constraint is not taken into account !
Exemple :
Let’s say you have this entity code
/**
* @ORM\Entity(repositoryClass="App\Repository\InvoiceRepository")
* @ApiResource(
* attributes={"pagination_enabled"=true, "pagination_items_per_page"="5"},
* normalizationContext={"groups"={"invoice_read"}},
* denormalizationContext={"disable_type_enforcement"=true},
* collectionOperations={"get", "post", "api_customers_invoices_get_subresource"={
* "normalization_context"={"groups"={"customers_invoices_read"}}
* }}
* )
*/
class Invoice
{
/**
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type="integer")
* @Groups({"invoice_read", "customer_read", "customer_item_read", "customers_invoices_read"})
*/
private $id;
/**
* @ORM\Column(type="float")
* @Groups({"invoice_read", "customer_read", "customer_item_read", "customers_invoices_read"})
* @Assert\NotBlank(message="Le montant est obligatoire")
* @Assert\Type(type="numeric", message="Le montant doit être un nombre")
*/
private $amount;
....
}
As you can see, the amount field is a Doctrine float and we also put a validation constraint on it to retrieve a nice an smooth ViolationError on the client side. But this is not the case, what we get on the client side is this :
{
"@context": "/api/contexts/Error",
"@type": "hydra:Error",
"hydra:title": "An error occurred",
"hydra:description": "The type of the \"amount\" attribute must be \"float\", \"string\" given.",
"trace": [
....
}
As you also noted, I used a context option for the denormalization which is disable_type_enforcement and I though it would cancel the validation of the attribute type and let the constraint do its own job.
It did not work.
Proposal for fixing :
So here is my proposal : in the AbstractItemNormalizer, on line 220, you have this call $this->validateType($attribute, $type, $value, $format);
which is triggering the Type Error.
Since the context is reachable in this function, we can lookup into the context for the disable_type_enforcement option, and if it is set to true, then we can avoid the call for validateType() :
if (true !== $context['disable_type_enforcement']) {
$this->validateType($attribute, $type, $value, $format);
}
So ? What do you think about it ? Will it break some things in ApiPlatform ? Or is it just a good and small enhancement ? Can I keep it that way in my application ?
Issue Analytics
- State:
- Created 5 years ago
- Comments:5 (3 by maintainers)
We recently fixed that in https://github.com/api-platform/core/pull/1957. Can you check if the 2.4 branch works for you? (https://github.com/api-platform/core/blob/2.4/src/Serializer/AbstractItemNormalizer.php#L341)
Closing then as it has been fixed. Feel free to reopen if necessary of course.