-
-
Notifications
You must be signed in to change notification settings - Fork 838
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
Support php7.4 nullable typed properties for JMS serializer. #2103
Support php7.4 nullable typed properties for JMS serializer. #2103
Conversation
Oops, it seems I need to move it out to a separate controller to avoid conflicts with <7.4 tests. |
c4cce49
to
ae1b7a6
Compare
It seems master branch is corrupted, so waiting for fix upstream, later I will rebase. |
@zviryatko could you rebase with last updates? Thanks |
e9a1979
to
323eee4
Compare
323eee4
to
0bee583
Compare
@shakaran finally did that 🙄 |
@DjordyKoert could you check this for quick merge if suitable? It is already rebased |
Sorry for the long wait! Thank you for contributing! |
I've already left that job where it was needed, but the frontend dev would be happy to hear that 😅 |
@DjordyKoert the code for this PR is very poor, its not checking a lot of conditions:
|
Hello @deluxetom, thank you for your opinion.
But is it reasonable to make property nullable if you have a default value? As I understand, you want to show in api that some property is optional for POST but how it should be described for GET? If it has a default value, then api users could rely on property that never be empty, so make it as non-nullable, but if you want to tell them that property could be null despite it has default value, then make it nullable 🤷
Not sure what the difference between the previous statement.
It shouldn't be difficult to add some if-condition to include this feature, but how it should be configured: site-wide or per model? Technically, some annotation can be added to per-model or even per-property like #[IgnoreRequired] or something, but it should be enabled by default or not. That's probably a question for the project maintainer.
It really means that nothing can be not required since there are many listeners. In that case, making any generated api doc based on the model is actually a bad idea because your model doesn't describe anything. I think that when api implementation is poor it creates so much questions and ad-hocs. But, you're welcome to add more conditions, the base part with tests already done. Or, at least you can just give more code examples with entities and desired results. |
Hey @zviryatko, I'm sorry for my tone in my last comment; I didn't mean any disrespect. My use case of this bundle creates an issue since most of the Doctrine entities are used for POST / PUT endpoints.
The issue with this is with Doctrine, if you make a property nullable, it will make the field nullable by default, when it shouldn't. Tools like I'll try to add more checks, and like you said, an optional attribute to ignore this automation could also work. Since this is in the JMS describer, I didn't see a way to use a JMS attribute for this yesterday. |
Ah, sorry too, just a hot morning. So, could you please give some examples of Entity definitions and desired apidoc results. Let's start from making tests and find some suitable solution to it. |
Here's an example of an entity having the issue with the fields being required: use Doctrine\ORM\Mapping as ORM;
use JMS\Serializer\Annotation as Serializer;
use OpenApi\Attributes as ApiDoc;
#[ORM\Entity]
class NotificationSettings
{
#[ORM\Column(type: Types::DATETIME_IMMUTABLE, nullable: false, options: ['default' => 'CURRENT_TIMESTAMP'])]
#[Serializer\Groups(['default', 'dated'])]
#[Serializer\Accessor(getter: 'getInsertDate', setter: 'setInsertDate')]
#[ApiDoc\Property(type: 'string')]
public \DateTimeImmutable $insertDate;
#[ORM\Column(type: Types::DATETIME_IMMUTABLE, nullable: false, options: ['default' => 'CURRENT_TIMESTAMP'])]
#[Serializer\Groups(['default', 'dated'])]
#[Serializer\Accessor(getter: 'getUpdateDate', setter: 'setUpdateDate')]
#[ApiDoc\Property(type: 'string')]
public \DateTimeImmutable $updateDate;
#[ORM\Column(type: Types::BOOLEAN, options: ['default' => false])]
#[Serializer\Groups(['default'])]
#[ApiDoc\Property(type: 'boolean')]
public bool $dontNotifyIfLive = false;
} Both dates are set automatically with doctrine listeners, they're always returned but we don't need them sent to the API. I'm not sure how we could define the required params with the JMS attributes to be honest. What do you think? |
Thanks for the example. I'm thinking that you're technically having two different models: one for POST with optional values and the second for GET with required. Those models aren't the same. But, I doubt anyone wants to define two models in such a situation, nor make property optional for both cases. Maybe the easiest workaround would be to add some parameter to #[Property] to control is required or not, and in what cases. For example, "hasDefault=true" could provide information that the property won't be empty, but doesn't require providing the value. The problem is that it is still two different models for POST and for GET. In swagger they must be treated as NotificationSettings1 and NotificationSettings2. (Technically it can be achieved with virtualProperty and serializerGroup but I don't think you want to go this way) Or it can magically detect that property is filled automatically with "default" orm/column value - which is a bad behavior, so I'd avoid such solution. Let's ask @DjordyKoert opinion. My final proposal is to introduce something like |
To add to this: This change causes a (further) regression for the On another note, maybe I'm misunderstanding, but why is the variable called @DjordyKoert Should this PR perhaps be reverted because of the mentioned regression? The person who made the PR seems to no longer require it, and it's breaking functionality for several people. |
I was already thinking about introducing something like this to simplify setting (or un-setting) required on a property #2287 (comment)
I think the way to go is by reverting this PR |
@zviryatko @thomask the PR has been reverted and is available in v4.29.0 |
In the case of php7.4 typed properties for JMS serializer there is no difference between nullable typed property and required one:
Spec is generated for both properties as optional, but the
$id
must be required.This PR adds support for marking fields as required automatically for php7.4 typed properties and for virtual properties based on their return type's nullability.