-
Notifications
You must be signed in to change notification settings - Fork 6k
[Scala] Default case class Option types to None for non-required fields #6790
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
[Scala] Default case class Option types to None for non-required fields #6790
Conversation
@@ -104,6 +104,12 @@ ext { | |||
jackson_version = "2.4.2" | |||
junit_version = "4.8.1" | |||
scala_test_version = "2.2.4" | |||
swagger_async_httpclient_version = "0.3.5" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like this wasn't added by this PR, but I haven't seen it elsewhere yet.
swagger-async-httpclient hasn't been updated in 3 years. Is there any reason we're not using an async http client that is current?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, not sure where this came from. Just a side effect of running the petstore sample scripts.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The Petstore security test samples (Scala) were not updated before.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, I should have explicitly mentioned that my second question was a general aside. It makes sense that the script added it, and the sample just hadn't been generated in a while.
@@ -12,7 +12,7 @@ case class {{classname}} ( | |||
{{#description}} | |||
/* {{{description}}} */ | |||
{{/description}} | |||
{{{name}}}: {{^required}}Option[{{/required}}{{datatype}}{{^required}}]{{/required}}{{#hasMore}},{{/hasMore}} | |||
{{{name}}}: {{^required}}Option[{{/required}}{{datatype}}{{^required}}] = None{{/required}}{{#hasMore}},{{/hasMore}} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So, there are three different states for properties in objects here: swagger spec's required = false means that objects don't require the property in the object. These should be defaulted to None. Then, there are the Scala semantics around avoiding nulls using Option[A]. It looks like this PR considers all nullable types as spec's optional? I think defaulting in the serializer config would account for all states.
How does this account for the state where a property is required, but nullable? Or would you consider this a non-issue?
I ask mainly because one of the sample types now has all constructor parameters with defaulted None args, which I don't think is valid in Swagger 2.0 specs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@gmarz did you have a chance to review the questions by @jimschubert ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How does this account for the state where a property is required, but nullable?
Can you give an example of such a case? I think this is a non-issue wrt to the Scala client. If a property is required, then it shouldn't be of type Option, IMO.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@gmarz "required" only pertains to the structure of a transport object, not the validation of data in that object.
See http://json-schema.org/latest/json-schema-validation.html#rfc.section.6.17.
The value of this keyword MUST be an array. Elements of this array, if any, MUST be strings, and MUST be unique.
An object instance is valid against this keyword if every item in the array is the name of a property in the instance.
Omitting this keyword has the same behavior as an empty array.
This means when Swagger Specification defines required
properties, it is saying that a document passed between systems must have the property.
For instance,
{
"title": "Written Article",
"type": "object",
"properties": {
"id": {
"title": "Article Identifier",
"type": "number",
"readOnly": true
},
"title": {
"title": "Article Title",
"type": "string"
},
"authorId": {
"type": "integer"
},
"imgData": {
"title": "Article Illustration (thumbnail)",
"type": "string",
"media": {
"binaryEncoding": "base64",
"type": "image/png"
}
}
},
"required" : ["id", "title", "authorId"]
}
Valid JSON objects, according to spec:
{ "id": 1, "title": "Some title", "authorId": 2 }
{ "id": 1, "title": null, "authorId": 2 }
An invalid JSON object:
{ "id": 1, "authorId": 2 }
Here, title
is a required property per the spec, but it is a nullable reference type (a String
). In Scala, we avoid nulls, so this would be Option[String]
as there are unfortunately no semantics in Swagger 2.0 Specifications to require non-null data within a property like this (there's min/max length, but those only pertain to string content and not nullability of a property's data).
I hope that clarifies.
I've considered adding support for an x-nullable
vendor extension so we can support this somewhat in Swagger 2.0 documents. Open API Specification 3.0 addresses this with the nullable
schema object property (see https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/3.0.0.md#schemaNullable).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jimschubert yes, thank you. That makes perfect sense.
Taking a step back though, this PR actually only changes the behavior to defaulting to None
for non-required fields ({{^required}}] = None{{/required}}
) and doesn't change how required, but nullable properties should be handled.
I ask mainly because one of the sample types now has all constructor parameters with defaulted None args, which I don't think is valid in Swagger 2.0 specs.
Can you point out where in the spec it says this is invalid? Shouldn't an empty body {}
be allowed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I looked and can't seem to find what I remembered seeing. There was a passage in JSON Schema spec which made it sound like a body required at least one key/value, but you're right { }
is a valid body.
I did notice that we don't seem to account for allowEmptyValue = false
, which is a similar concern.
I'll revisit when I'm not on mobile and see if I can find the place in the spec that I'm thinking of.
Again, you're right that the default to None
here seems to be focused and outside of the concerns I stated above. I may need to open a new issue if I find the spec area that concerned me.
Thanks for following up on my comment!
Sorry I finally got around to pulling the code and checking it out. It looks good to me! |
The Travis CI job actually passed: https://travis-ci.org/swagger-api/swagger-codegen/builds/300009630?utm_source=github_status&utm_medium=notification Merging this into master. Thanks @jimschubert for reviewing. |
* master: (101 commits) [Swift4] Allow for custom dateformatter to be used (swagger-api#6672) [haskell-http-client] fix bug when generating models-only (swagger-api#6931) fix typo: crediential => credential minor typo fix [csharp] fix enum serialization of first value (swagger-api#6873) [PHP] Improve docs and README (swagger-api#6935) Binary mode for file deserialization in python (swagger-api#6936) add python tornado test to travis [Python/tornado] add integration tests and fix bugs (swagger-api#6925) Fix PHP passes response body to ApiException (swagger-api#6923) [TypeScript][Node] Resolve TS2532 error (swagger-api#6932) skip "all" shell script minor formatting change Fixes Issue swagger-api#6841, Map for accessing additionalProperties is generated. (swagger-api#6886) add tsloughter as owner erlang WIP: initial commit for Erlang client generator (swagger-api#6502) add back php client test Switch Travis image from MacOS to Linux (swagger-api#6937) add link to ebook [Scala] Default case class Option types to None for non-required fields (swagger-api#6790) ...
PR checklist
./bin/
to update Petstore sample so that CIs can verify the change. (For instance, only need to run./bin/{LANG}-petstore.sh
and./bin/security/{LANG}-petstore.sh
if updating the {LANG} (e.g. php, ruby, python, etc) code generator or {LANG} client's mustache templates). Windows batch files can be found in.\bin\windows\
.3.0.0
branch for changes related to OpenAPI spec 3.0. Default:master
.Description of the PR
Similar to #6538, this defaults
Option
types toNone
for non-required fields in the model case classes./cc @clasnake @jimschubert @ramzimaalej @wing328