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

Add support for enum path parameters #738

Merged
merged 1 commit into from
Aug 29, 2018

Conversation

maros7
Copy link

@maros7 maros7 commented Aug 28, 2018

This is related to #322. I've taken a stab at implementing enum type path parameter support.

I have updated protoc-gen-swagger to render enum path parameters correctly. However, since swagger-codegen-cli 2.2.2 doesn't support generating go enums (it was added in a later version, see swagger-api/swagger-codegen#5635) I also had to add some helper functions to make the tests pass correctly.

protoc-gen-grpc-gateway was of course updated to handle enum path parameters. The runtime enum convert function will return an int32 that will be type casted to an enum, which is generated via the update to the template.

Any feedback on my take on this is appreciated.

Related to grpc-ecosystem#322

Updated protoc-gen-swagger to output enum path parameters correctly

Updated protoc-gen-grpc-gateway to handle enum path parameters

Regenerated examples

Added pathenum proto for an externally imported enum example and verification

Added enum_helper.go to handle the lack of enum support in the swagger-codegen-cli 2.2.2 for Go, see swagger-api/swagger-codegen#5635

Fixed browser integration test cases

Updated bazel config

Fixed last, faulty bazel config

Updated integration test case to test both index == 0 and index > 0 for enums
@codecov-io
Copy link

Codecov Report

❗ No coverage uploaded for pull request base (master@e679739). Click here to learn what that means.
The diff coverage is 28.57%.

Impacted file tree graph

@@            Coverage Diff            @@
##             master     #738   +/-   ##
=========================================
  Coverage          ?   55.36%           
=========================================
  Files             ?       30           
  Lines             ?     3213           
  Branches          ?        0           
=========================================
  Hits              ?     1779           
  Misses            ?     1259           
  Partials          ?      175
Impacted Files Coverage Δ
runtime/convert.go 44.89% <0%> (ø)
protoc-gen-grpc-gateway/descriptor/types.go 44.53% <0%> (ø)
protoc-gen-swagger/genswagger/template.go 38.95% <28.57%> (ø)
protoc-gen-grpc-gateway/gengateway/generator.go 38.77% <40%> (ø)
protoc-gen-grpc-gateway/gengateway/template.go 58.06% <66.66%> (ø)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update e679739...7cf77b0. Read the comment docs.

Copy link
Collaborator

@johanbrandhorst johanbrandhorst left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks great! Just a few questions.

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}"
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}"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💯

@@ -594,8 +595,13 @@ func renderServices(services []*descriptor.Service, paths swaggerPathsObject, re
return fmt.Errorf("only primitive and well-known types are allowed in path parameters")
}
case pbdescriptor.FieldDescriptorProto_TYPE_ENUM:
paramType = fullyQualifiedNameToSwaggerName(parameter.Target.GetTypeName(), reg)
paramType = "string"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems the handler below handles both the numerical and string representations of an enum, should we really hardcode this to string?

Copy link
Author

@maros7 maros7 Aug 29, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree. I chose to use the same logic as already existed for enums in query params, see https://github.com/grpc-ecosystem/grpc-gateway/blob/master/runtime/query.go#L339-L356. Do you know the rationale of supporting numerical, i.e. supporting that you input an enum by its index? From my perspective string support is sufficient and I'd like to update the convert Enum function to only support string. But please share any rationale behind supporting both first.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think using the query params precedent is good. I think the reason we want both the numerical representation and the string representation to work is because they're both valid ways of representing the enum value, and the user isn't able to configure which they prefer (unlike for the marshaller), so we have to support both. Anyway, I'm happy to keep this the same as the query params, there isn't really an important distinction in the URL anyway (unlike in JSON).

// Enum converts the given string into an int32 that should be type casted into the
// correct enum proto type.
func Enum(val string, enumValMap map[string]int32) (int32, error) {
e, ok := enumValMap[val]
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This lookup means we define the correct enum values as the strings generated by the go Protobuf implementation. Is this appropriate? It'll be things like MyEnum_FIRST_VALUE etc. Is there some way we can use the values from the protofile directly (i.e. FIRST_VALUE). I like having the protofile content as the source of truth.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure I follow. The convert Enum function will use the name->index map that is generated by the proto compiler, see e.g. grpc-gateway/examples/proto/examplepb/a_bit_of_everything.pb.go. That map is provided to the convert Enum function when conversion from path parameters to protobuf is done, see e.g. grpc-gateway/examples/proto/examplepb/a_bit_of_everything.pb.gw.go. So not sure exactly what you mean.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, my bad, the values aren't prefixed. Carry on!

@johanbrandhorst
Copy link
Collaborator

johanbrandhorst commented Aug 29, 2018

This LGTM, @achew22, @ivucica want to have a look before I merge?

@johanbrandhorst johanbrandhorst merged commit ca6e9cd into grpc-ecosystem:master Aug 29, 2018
@johanbrandhorst
Copy link
Collaborator

Thanks for your contribution!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants