-
Notifications
You must be signed in to change notification settings - Fork 2.2k
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
gen-grpc-gateway, gen-openapiv2: add support for proto3 optional #1951
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 bazelbuild/rules_go#2788 on adding protocopts to rules_go |
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.
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. |
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.
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.
@@ -458,7 +460,7 @@ service ABitOfEverythingService { | |||
// This API creates a new ABitOfEverything | |||
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This might break the promise of optional values
internal/descriptor/types.go
Outdated
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually I read a bit more about it. It does use oneof under the hood.
3c64f2c
to
a938514
Compare
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.
LGTM
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/protogen
package, each plugin needs to explicitly enable support for proto3 optional fields. This change does exactly that. Note thatgen-openapiv2
still 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-openapiv2
which actually might be required to deliver a valid experience.