gen-grpc-gateway, gen-openapiv2: add support for proto3 optional#1951
Conversation
1a5b78d to
50ee7ec
Compare
50ee7ec to
756c77b
Compare
|
@johanbrandhorst I will need some help with failing bazel job. It seems that |
|
@adambabik I think you might be blocked by bazel-contrib/rules_go#2788 on adding protocopts to rules_go |
johanbrandhorst
left a comment
There was a problem hiding this comment.
This LGTM, but I'm still slightly worried that we should do something special here. Do you think you could add an integration test that uses this new optional string? The test would go here: https://github.com/grpc-ecosystem/grpc-gateway/blob/master/examples/internal/integration/integration_test.go.
cca9e5d to
4700507
Compare
|
@johanbrandhorst thanks for the suggestion. Adding a case to the integration tests revealed one more missing piece, that is optional fields require different converters. I used converters from proto2 because they return pointers. It would be nice to move them to more generic place I think. It's for another PR :) I didn't add so through testing for optional fields as it is for repeated. If it's not enough, let me know. |
johanbrandhorst
left a comment
There was a problem hiding this comment.
Thanks for the new test Adam, I think it exposes an important question - we should probably disallow optional fields in path parameters, since they're required by definition.
| rpc Create(ABitOfEverything) returns (ABitOfEverything) { | ||
| option (google.api.http) = { | ||
| post: "/v1/example/a_bit_of_everything/{float_value}/{double_value}/{int64_value}/separator/{uint64_value}/{int32_value}/{fixed64_value}/{fixed32_value}/{bool_value}/{string_value=strprefix/*}/{uint32_value}/{sfixed32_value}/{sfixed64_value}/{sint32_value}/{sint64_value}/{nonConventionalNameValue}/{enum_value}/{path_enum_value}/{nested_path_enum_value}/{enum_value_annotation}" | ||
| post: "/v1/example/a_bit_of_everything/{float_value}/{double_value}/{int64_value}/separator/{uint64_value}/{int32_value}/{fixed64_value}/{fixed32_value}/{bool_value}/{string_value=strprefix/*}/{uint32_value}/{sfixed32_value}/{sfixed64_value}/{sint32_value}/{sint64_value}/{nonConventionalNameValue}/{enum_value}/{path_enum_value}/{nested_path_enum_value}/{enum_value_annotation}/{optional_string_value}" |
There was a problem hiding this comment.
This is an interesting case, because if optional_string_value is truly optional, should it be possible to have it be a path parameter? Will our parser handle the case where this is unset? We may need to trigger a generation-time error when a user does this?
There was a problem hiding this comment.
That's a good idea! Is there a place where I could document how optional fields behave?
| { | ||
| "name": "optionalStringValue", | ||
| "in": "path", | ||
| "required": true, |
There was a problem hiding this comment.
This might break the promise of optional values
| if c.Target.GetProto3Optional() { | ||
| // Continue as a proto3 optional field does not need a special treatment. | ||
| // This condition is required as otherwise it is matched by `c.Target.OneofIndex != nil`. | ||
| } else if c.Target.OneofIndex != nil { // check if it is a oneOf field |
There was a problem hiding this comment.
Can we invert this to avoid an else?
| if c.Target.GetProto3Optional() { | |
| // Continue as a proto3 optional field does not need a special treatment. | |
| // This condition is required as otherwise it is matched by `c.Target.OneofIndex != nil`. | |
| } else if c.Target.OneofIndex != nil { // check if it is a oneOf field | |
| if !c.Target.GetProto3Optional() && c.Target.OneofIndex != nil { // check if it is a oneOf field |
There was a problem hiding this comment.
I wanted to separate proto3 optional and oneof cases, hence, separate blocks but I can also join them. I will keep the explanation.
There was a problem hiding this comment.
Actually I read a bit more about it. It does use oneof under the hood.
3c64f2c to
a938514
Compare
|
Bazel failure seems genuine - we need to configure |
|
Please rebase on |
a938514 to
d6767e9
Compare
|
protoc 3.15 was released a few hours ago....
|
|
Well... I don't think you're blocked by rules_go any more then 😉 |
|
Whoop I didn't notice that this PR was created before creating a new one #1988 after we decided to close the attempt I made months ago #1834. My approach in the new PR is to just make Feel free to do whatever you want with this new PR. |
d6767e9 to
bbd3444
Compare
Fixes #1278.
Even though, the main piece of code was added in
google.golang.org/protobuf/compiler/protogenpackage, each plugin needs to explicitly enable support for proto3 optional fields. This change does exactly that. Note thatgen-openapiv2still does not fully benefit fromprotogen, hence, there are two helper methods enabling the feature in two different ways.Also, this change does not treat optional fields in any different way in neither
gen-grpc-gateway, norgen-openapiv2which actually might be required to deliver a valid experience.