Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

RFC: denormalize - do not set null values on not nullable properties #1911

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed

RFC: denormalize - do not set null values on not nullable properties #1911

wants to merge 1 commit into from

Conversation

bendavies
Copy link
Contributor

@bendavies bendavies commented Apr 30, 2018

Q A
Bug fix? yes?
New feature? no
BC breaks? no?
Deprecations? no
Tests pass? yes
Fixed tickets
License MIT
Doc PR

This was discussed a little bit on slack this afternoon.
Should we not call setters with null values if the type is not nullable?

This seems to be consistent with the check on line 177.

if (null === $value && $type->isNullable()) {
$this->setValue($object, $attribute, $value);
return;

We should respect the property info type isNullable value.

This is mainly to prevent denormalize errors when an api's resource may have a not nullable setter: setFoo(string $foo) but the api request as come in as {"foo": null}

Not sure what the drawbacks are here. I'm sure someone will point something out.

further work if this PR is deemed correct:
The same check should also be done when denormalizing relations.

@teohhanhui
Copy link
Contributor

Should it fail silently? I think it should result in a HTTP 400 status code.

@teohhanhui teohhanhui added the bug label Apr 30, 2018
@bendavies
Copy link
Contributor Author

In my API, I have a NotBlank constraint on the property which satisfies that.

@soyuka
Copy link
Member

soyuka commented Apr 30, 2018

In my API, I have a NotBlank constraint on the property which satisfies that.

This is always the same issue (I guess) :p. What if you don't have such constraint?

@teohhanhui
Copy link
Contributor

Either way, I don't think the normalizer should silently ignore a null value that it cannot set as requested. It should throw an exception. It's then up to the calling code to handle it, and in API Platform we should make sure that it (eventually) becomes a HTTP 400...

@bendavies
Copy link
Contributor Author

@soyuka

This is always the same issue (I guess) :p. What if you don't have such constraint?

then you'll have a database violation on insert.

@bendavies
Copy link
Contributor Author

@teohhanhui that seems like a nice solution.

@soyuka
Copy link
Member

soyuka commented Apr 30, 2018

Either way, I don't think the normalizer should silently ignore a null value that it cannot set as requested. It should throw an exception. It's then up to the calling code to handle it, and in API Platform we should make sure that it (eventually) becomes a HTTP 400...

Issues stays the same when you'd expect a ConstraintValidation instead of a Normalization exception :). And we will not change the listeners order (as discussed in other issues that I'm lazy to look up right now :p).

@bendavies
Copy link
Contributor Author

either way it needs to be handled somehow. at the moment a 500 isn't really acceptable.

@dunglas
Copy link
Member

dunglas commented May 2, 2018

A 400 should be thrown. Actually, Symfony's ObjectNormalizer should already throw in this case because if this check: https://github.com/symfony/symfony/blob/master/src/Symfony/Component/Serializer/Normalizer/AbstractObjectNormalizer.php#L342

We need to figure out why it's not the case.

@dunglas
Copy link
Member

dunglas commented May 2, 2018

https://github.com/bendavies/core/blob/3490493718982044420b98335787f40fabdfb4e6/src/Serializer/AbstractItemNormalizer.php#L230 should already trigger an error :|

php > var_dump(is_int(null));
bool(false)

@bendavies
Copy link
Contributor Author

@dunglas i'll take a look.

@bendavies
Copy link
Contributor Author

bendavies commented May 9, 2018

@dunglas

  1. https://github.com/symfony/symfony/blob/cb2a77b24bc01a08787fcf9b4700fd5e03884155/src/Symfony/Component/Serializer/Normalizer/AbstractObjectNormalizer.php#L297
    $this->propertyTypeExtractor is null, so the below is never evaluated. bug in service def?
  2. https://github.com/bendavies/core/blob/3490493718982044420b98335787f40fabdfb4e6/src/Serializer/AbstractItemNormalizer.php#L230
    the issue here is the doctrine type specifies nullable=true, but the setter does not allow null. the doctrine extractor takes precedence?

@dunglas
Copy link
Member

dunglas commented May 10, 2018

  1. Yes it's intended, we overrode this logic by our own metadata system
  2. Ok, so it's not really a bug, indeed the Doctrine extractor takes precedence. It should be fixed on Symfony side (but IMO the best is to fix the code).

@dunglas
Copy link
Member

dunglas commented May 10, 2018

Mutators should be in sync with the Doctrine mapping. To get the intended behavior I would:

  • Make the setter accept null values
  • Add a @NotNull validation assertion on the property

@bendavies
Copy link
Contributor Author

ok, sorry the actual problem is for non nullable resources relations, and passing in null.

setFoo(Foo $foo)

...

{"foo": null}

This will trigger a 500, as there is no nullable check here:
https://github.com/api-platform/core/pull/1911/files#diff-3e45e8e6ce08f8a7cbbbda1601d5ff29L197

@dunglas
Copy link
Member

dunglas commented May 10, 2018

Ok, we should throw in this case.

@bendavies
Copy link
Contributor Author

thanks, i'll work on this.

@bendavies
Copy link
Contributor Author

@dunglas what should i be throwing here? Is there currently a handler that converts whichever exception it is to a validation error?

@bendavies
Copy link
Contributor Author

ahh, ApiPlatform\Core\Exception\InvalidArgumentException returns a 400.

@soyuka
Copy link
Member

soyuka commented Feb 15, 2019

What's the status on this @bendavies ?

@bendavies
Copy link
Contributor Author

wow old one...no idea.
i'll take a look next week.

@teohhanhui
Copy link
Contributor

ahh, ApiPlatform\Core\Exception\InvalidArgumentException returns a 400.

We should throw Symfony\Component\Serializer\Exception\UnexpectedValueException instead.

@flug
Copy link
Contributor

flug commented Nov 14, 2019

@bendavies Up is this pull request still valid?

@alanpoulain
Copy link
Member

Closing this PR because it's too old and I can't reproduce.

@bendavies
Copy link
Contributor Author

this will be resolved by symfony/symfony#42502

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants
Morty Proxy This is a proxified and sanitized view of the page, visit original site.