Skip to content
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

Required.AllowNull does not mark property as required #402

Closed
basilfx opened this issue Mar 23, 2022 · 12 comments · Fixed by #506
Closed

Required.AllowNull does not mark property as required #402

basilfx opened this issue Mar 23, 2022 · 12 comments · Fixed by #506
Labels
enhancement New feature or request v1.5.1

Comments

@basilfx
Copy link

basilfx commented Mar 23, 2022

Describe the issue
According to the documentation, only Required.Always and Required.DisallowNull in a JsonProperty attribute will mark a property as required in the schema.

Required.AllowNull should also mark it as required. The documentation states: "The property must be defined in JSON but can be a null value." It must be present in the JSON, therefore it must be marked as required.

Required.DisallowNull should not mark it as required. The documentation states: "The property is not required but it cannot be a null value." It may be present in the JSON, therefore it should not be marked as required.

To Reproduce
See this demonstration project: https://github.com/basilfx/azure-functions-openapi-function-timespan (yes, same project as #401).

Note how MyInstance.MyNullableTimeSpan has Required = Required.AllowNull, yet it is not marked as required in the schema. As a work-around, add the Required attribute.

Expected behavior
The property is marked as required in the inferred schema.

Screenshots
Schermafbeelding 2022-03-23 om 22 38 54

Environment (please complete the following information, if applicable):

  • OS: macOS
  • Azure Functions v4
  • .NET SDK 6.0.102
  • OpenAPI Extension 1.2.0
@justinyoo
Copy link
Contributor

@basilfx Thanks for the issue. I intepreted both .AllowNull and .DisallowNull as completely opposite. I rather focused on the later part of those statements:

  • .AllowNull: ... can be a null value ➡️ not "required"
  • .DisallowNull: ... cannot be a null value ➡️ "required"

@basilfx
Copy link
Author

basilfx commented Oct 18, 2022

@justinyoo Any update on this issue? Anything I can do to help?

@William-Froelich
Copy link
Contributor

I'm also seeing this issue. Our API relies heavily on DisallowNull.

@William-Froelich
Copy link
Contributor

The documentation for azure-functions-openapi-extensions states that .DisallowNull indicates a field is always required. but from the Newtonsoft Documentation, this statement is wrong:

From Src/Newtonsoft.Json/Required.cs

//
// Summary:
//     Indicating whether a property is required.
public enum Required
{
    //
    // Summary:
    //     The property is not required. The default state.
    Default = 0,
    //
    // Summary:
    //     The property must be defined in JSON but can be a null value.
    AllowNull = 1,
    //
    // Summary:
    //     The property must be defined in JSON and cannot be a null value.
    Always = 2,
    //
    // Summary:
    //     The property is not required but it cannot be a null value.
    DisallowNull = 3
}

It looks like the change should be pretty trivial in both src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/ObjectTypeVisitor.cs and src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/RecursiveObjectTypeVisitor.cs. .DisallowNull would be replaced with .AllowNull to match Newtonsoft's design.

I'd be happy to make the updates if you agree it should be changed.

@William-Froelich
Copy link
Contributor

#336 relates to this issue.

@timosnel
Copy link

@justinyoo any chance you can take a look at the PR of @William-Froelich?

For us this really prevents production-ready usage of this extension, because our generated client marks everything as optional even though the JsonProperty is correct. Changing it to Required.Always would break serialization.

@justinyoo justinyoo linked a pull request Dec 23, 2022 that will close this issue
@justinyoo
Copy link
Contributor

I'm still trying to understand whether my interpretation of those properties AllowNull and DisallowNull is correct or not.

From the Newtonsoft.Json point of view, your change makes sense, but the OpenAPI spec perspective, I'm still thinking my interpretation is more appropriate.

  • required from the OpenAPI spec means the property MUST have a value (null is not a value).
  • AllowNull from Newtonsoft.Json means it MUST be shown while serialising and allows null.

@William-Froelich
Copy link
Contributor

@justinyoo I just looked over OpenAPI spec for parameters and I disagree with that assessment. There's a required property and as of OpenAPI version 3 a nullable property. required only indicates if something must be present in your JSON request and nullable only indicates if the value null is allowed.

From OpenAPI:
Required:
image

Nullable:
image

These two parameters are not mutually-exclusive. A field can be marked required but also marked nullable.

I also found an interesting discussion from 2017 on Stack Overflow about the concepts and I think some confusion may come from null not being allowed because it failed type coercion, not because of the required flag. (in other words null did not match a given type such as string so was not accepted by the validator)

I don't think it makes sense to add any other meaning to required beyond enforcing presence in the JSON. I also think for the four values from Netwonsoft I shared the documentation for previously, the property mappings would be:

Default: 
  Nullable: False ? // This one I wasn't sure on. Newtonsoft documentation only states "The property is not required. The default state."
  Required: False
AllowNull
  Nullable: True
  Required: True
Always
  Nullable: False
  Required: True
DisallowNull
  Nullable: False
  Required: False

My PR only addresses the Required state on this. Maybe we need to include Nullable for Api Spec version 3+?

@William-Froelich
Copy link
Contributor

@justinyoo have you had any time to look into this further and look over what I posted? How can I help get this resolved faster?

@justinyoo
Copy link
Contributor

@William-Froelich Now I understand your assessment, and I should update my interpretation.

Then, we should also take care of both Required and Nullable attributes. Would you please be able to include both? It will be then included in the next release.

@justinyoo justinyoo added enhancement New feature or request v1.6.0 and removed triage labels Jan 16, 2023
@justinyoo justinyoo added this to the Release 2023Q1 - v1.6.0 milestone Jan 16, 2023
@William-Froelich
Copy link
Contributor

Sure, I'll update the PR.

Would you prefer I add it to the ObjectTypeVisitor and RecursiveObjectTypeVisitor classes or somewhere else?

@justinyoo
Copy link
Contributor

Nullable has been covered by the PR, #504 so, please take a look at that part and apply it to yours accordingly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request v1.5.1
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants