Skip to content

Commit

Permalink
Add support for enum path parameters
Browse files Browse the repository at this point in the history
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
  • Loading branch information
Marcus Rosén committed Aug 28, 2018
1 parent e679739 commit 7cf77b0
Show file tree
Hide file tree
Showing 26 changed files with 717 additions and 200 deletions.
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ EXAMPLES=examples/proto/examplepb/echo_service.proto \
EXAMPLE_SVCSRCS=$(EXAMPLES:.proto=.pb.go)
EXAMPLE_GWSRCS=$(EXAMPLES:.proto=.pb.gw.go)
EXAMPLE_SWAGGERSRCS=$(SWAGGER_EXAMPLES:.proto=.swagger.json)
EXAMPLE_DEPS=examples/proto/sub/message.proto examples/proto/sub2/message.proto
EXAMPLE_DEPS=examples/proto/pathenum/path_enum.proto examples/proto/sub/message.proto examples/proto/sub2/message.proto
EXAMPLE_DEPSRCS=$(EXAMPLE_DEPS:.proto=.pb.go)

EXAMPLE_CLIENT_DIR=examples/clients
Expand Down Expand Up @@ -182,7 +182,7 @@ $(RESPONSE_BODY_EXAMPLE_SRCS): $(RESPONSE_BODY_EXAMPLE_SPEC)
$(EXAMPLE_CLIENT_DIR)/responsebody/git_push.sh \
$(EXAMPLE_CLIENT_DIR)/responsebody/.travis.yml

examples: $(EXAMPLE_SVCSRCS) $(EXAMPLE_GWSRCS) $(EXAMPLE_DEPSRCS) $(EXAMPLE_SWAGGERSRCS) $(EXAMPLE_CLIENT_SRCS)
examples: $(EXAMPLE_DEPSRCS) $(EXAMPLE_SVCSRCS) $(EXAMPLE_GWSRCS) $(EXAMPLE_SWAGGERSRCS) $(EXAMPLE_CLIENT_SRCS)
test: examples
go test -race $(PKG)/...
go test -race $(PKG)/examples/integration -args -network=unix -endpoint=test.sock
Expand Down
6 changes: 6 additions & 0 deletions examples/browser/a_bit_of_everything_service.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ describe('ABitOfEverythingService', function() {
sint32_value: 2147483647,
sint64_value: "4611686018427387903",
nonConventionalNameValue: "camelCase",
enum_value: "ONE",
path_enum_value: "DEF",
nested_path_enum_value: "JKL",
};

beforeEach(function(done) {
Expand Down Expand Up @@ -72,6 +75,9 @@ describe('ABitOfEverythingService', function() {
sint32_value: 2147483647,
sint64_value: "4611686018427387903",
nonConventionalNameValue: "camelCase",
enum_value: "ONE",
path_enum_value: "DEF",
nested_path_enum_value: "JKL",

nested: [
{ name: "bar", amount: 10 },
Expand Down
10 changes: 9 additions & 1 deletion examples/clients/abe/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,21 @@ go_library(
"configuration.go",
"echo_rpc_api.go",
"echo_service_api.go",
"enum_helper.go",
"examplepb_a_bit_of_everything.go",
"examplepb_body.go",
"examplepb_numeric_enum.go",
"message_path_enum_nested_path_enum.go",
"nested_deep_enum.go",
"pathenum_path_enum.go",
"protobuf_empty.go",
"sub_string_message.go",
],
importpath = "github.com/grpc-ecosystem/grpc-gateway/examples/clients/abe",
deps = ["@com_github_go_resty_resty//:go_default_library"],
deps = [
"//examples/proto/examplepb:go_default_library",
"//examples/proto/pathenum:go_default_library",
"//runtime:go_default_library",
"@com_github_go_resty_resty//:go_default_library"
],
)
16 changes: 13 additions & 3 deletions examples/clients/abe/a_bit_of_everything_service_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,13 +57,16 @@ func NewABitOfEverythingServiceApiWithBasePath(basePath string) *ABitOfEverythin
* @param sint32Value
* @param sint64Value
* @param nonConventionalNameValue
* @param enumValue
* @param pathEnumValue
* @param nestedPathEnumValue
* @return *ExamplepbABitOfEverything
*/
func (a ABitOfEverythingServiceApi) Create(floatValue float32, doubleValue float64, int64Value string, uint64Value string, int32Value int32, fixed64Value string, fixed32Value int64, boolValue bool, stringValue string, uint32Value int64, sfixed32Value int32, sfixed64Value string, sint32Value int32, sint64Value string, nonConventionalNameValue string) (*ExamplepbABitOfEverything, *APIResponse, error) {
func (a ABitOfEverythingServiceApi) Create(floatValue float32, doubleValue float64, int64Value string, uint64Value string, int32Value int32, fixed64Value string, fixed32Value int64, boolValue bool, stringValue string, uint32Value int64, sfixed32Value int32, sfixed64Value string, sint32Value int32, sint64Value string, nonConventionalNameValue string, enumValue string, pathEnumValue string, nestedPathEnumValue string) (*ExamplepbABitOfEverything, *APIResponse, error) {

var localVarHttpMethod = strings.ToUpper("Post")
// create path and map variables
localVarPath := a.Configuration.BasePath + "/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}/{uint32_value}/{sfixed32_value}/{sfixed64_value}/{sint32_value}/{sint64_value}/{nonConventionalNameValue}"
localVarPath := a.Configuration.BasePath + "/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}/{uint32_value}/{sfixed32_value}/{sfixed64_value}/{sint32_value}/{sint64_value}/{nonConventionalNameValue}/{enum_value}/{path_enum_value}/{nested_path_enum_value}"
localVarPath = strings.Replace(localVarPath, "{"+"float_value"+"}", fmt.Sprintf("%v", floatValue), -1)
localVarPath = strings.Replace(localVarPath, "{"+"double_value"+"}", fmt.Sprintf("%v", doubleValue), -1)
localVarPath = strings.Replace(localVarPath, "{"+"int64_value"+"}", fmt.Sprintf("%v", int64Value), -1)
Expand All @@ -79,6 +82,9 @@ func (a ABitOfEverythingServiceApi) Create(floatValue float32, doubleValue float
localVarPath = strings.Replace(localVarPath, "{"+"sint32_value"+"}", fmt.Sprintf("%v", sint32Value), -1)
localVarPath = strings.Replace(localVarPath, "{"+"sint64_value"+"}", fmt.Sprintf("%v", sint64Value), -1)
localVarPath = strings.Replace(localVarPath, "{"+"nonConventionalNameValue"+"}", fmt.Sprintf("%v", nonConventionalNameValue), -1)
localVarPath = strings.Replace(localVarPath, "{"+"enum_value"+"}", fmt.Sprintf("%v", enumValue), -1)
localVarPath = strings.Replace(localVarPath, "{"+"path_enum_value"+"}", fmt.Sprintf("%v", pathEnumValue), -1)
localVarPath = strings.Replace(localVarPath, "{"+"nested_path_enum_value"+"}", fmt.Sprintf("%v", nestedPathEnumValue), -1)

localVarHeaderParams := make(map[string]string)
localVarQueryParams := url.Values{}
Expand Down Expand Up @@ -530,6 +536,8 @@ func (a ABitOfEverythingServiceApi) GetMessageWithBody(id string, body Examplepb
* @param bytesValue
* @param uint32Value
* @param enumValue - ZERO: ZERO means 0 - ONE: ONE means 1
* @param pathEnumValue
* @param nestedPathEnumValue
* @param sfixed32Value
* @param sfixed64Value
* @param sint32Value
Expand All @@ -541,7 +549,7 @@ func (a ABitOfEverythingServiceApi) GetMessageWithBody(id string, body Examplepb
* @param repeatedEnumValue repeated enum value. it is comma-separated in query. - ZERO: ZERO means 0 - ONE: ONE means 1
* @return *ProtobufEmpty
*/
func (a ABitOfEverythingServiceApi) GetQuery(uuid string, singleNestedName string, singleNestedAmount int64, singleNestedOk string, floatValue float32, doubleValue float64, int64Value string, uint64Value string, int32Value int32, fixed64Value string, fixed32Value int64, boolValue bool, stringValue string, bytesValue string, uint32Value int64, enumValue string, sfixed32Value int32, sfixed64Value string, sint32Value int32, sint64Value string, repeatedStringValue []string, oneofString string, nonConventionalNameValue string, timestampValue time.Time, repeatedEnumValue []string) (*ProtobufEmpty, *APIResponse, error) {
func (a ABitOfEverythingServiceApi) GetQuery(uuid string, singleNestedName string, singleNestedAmount int64, singleNestedOk string, floatValue float32, doubleValue float64, int64Value string, uint64Value string, int32Value int32, fixed64Value string, fixed32Value int64, boolValue bool, stringValue string, bytesValue string, uint32Value int64, enumValue string, pathEnumValue string, nestedPathEnumValue string, sfixed32Value int32, sfixed64Value string, sint32Value int32, sint64Value string, repeatedStringValue []string, oneofString string, nonConventionalNameValue string, timestampValue time.Time, repeatedEnumValue []string) (*ProtobufEmpty, *APIResponse, error) {

var localVarHttpMethod = strings.ToUpper("Get")
// create path and map variables
Expand Down Expand Up @@ -573,6 +581,8 @@ func (a ABitOfEverythingServiceApi) GetQuery(uuid string, singleNestedName strin
localVarQueryParams.Add("bytes_value", a.Configuration.APIClient.ParameterToString(bytesValue, ""))
localVarQueryParams.Add("uint32_value", a.Configuration.APIClient.ParameterToString(uint32Value, ""))
localVarQueryParams.Add("enum_value", a.Configuration.APIClient.ParameterToString(enumValue, ""))
localVarQueryParams.Add("path_enum_value", a.Configuration.APIClient.ParameterToString(pathEnumValue, ""))
localVarQueryParams.Add("nested_path_enum_value", a.Configuration.APIClient.ParameterToString(nestedPathEnumValue, ""))
localVarQueryParams.Add("sfixed32_value", a.Configuration.APIClient.ParameterToString(sfixed32Value, ""))
localVarQueryParams.Add("sfixed64_value", a.Configuration.APIClient.ParameterToString(sfixed64Value, ""))
localVarQueryParams.Add("sint32_value", a.Configuration.APIClient.ParameterToString(sint32Value, ""))
Expand Down
46 changes: 46 additions & 0 deletions examples/clients/abe/enum_helper.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package abe

import (
pbexamplepb "github.com/grpc-ecosystem/grpc-gateway/examples/proto/examplepb"
pbpathenum "github.com/grpc-ecosystem/grpc-gateway/examples/proto/pathenum"
"github.com/grpc-ecosystem/grpc-gateway/runtime"
)

// String returns a string representation of "NumericEnum"
func (e ExamplepbNumericEnum) String() string {
return pbexamplepb.NumericEnum_ONE.String()
}

// UnmarshalJSON does a no-op unmarshal to ExamplepbNumericEnum.
// It just validates that the input is sane.
func (e ExamplepbNumericEnum) UnmarshalJSON(b []byte) error {
return unmarshalJSONEnum(b, pbexamplepb.NumericEnum_value)
}

// String returns a string representation of "MessagePathEnum"
func (e MessagePathEnumNestedPathEnum) String() string {
return pbpathenum.MessagePathEnum_JKL.String()
}

// UnmarshalJSON does a no-op unmarshal to MessagePathEnumNestedPathEnum.
// It just validates that the input is sane.
func (e MessagePathEnumNestedPathEnum) UnmarshalJSON(b []byte) error {
return unmarshalJSONEnum(b, pbpathenum.MessagePathEnum_NestedPathEnum_value)
}

// String returns a string representation of "PathEnum"
func (e PathenumPathEnum) String() string {
return pbpathenum.PathEnum_DEF.String()
}

// UnmarshalJSON does a no-op unmarshal to PathenumPathEnum.
// It just validates that the input is sane.
func (e PathenumPathEnum) UnmarshalJSON(b []byte) error {
return unmarshalJSONEnum(b, pbpathenum.PathEnum_value)
}

func unmarshalJSONEnum(b []byte, enumValMap map[string]int32) error {
val := string(b[1 : len(b)-1])
_, err := runtime.Enum(val, enumValMap)
return err
}
4 changes: 4 additions & 0 deletions examples/clients/abe/examplepb_a_bit_of_everything.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@ type ExamplepbABitOfEverything struct {

EnumValue ExamplepbNumericEnum `json:"enum_value,omitempty"`

PathEnumValue PathenumPathEnum `json:"path_enum_value,omitempty"`

NestedPathEnumValue MessagePathEnumNestedPathEnum `json:"nested_path_enum_value,omitempty"`

Sfixed32Value int32 `json:"sfixed32_value,omitempty"`

Sfixed64Value string `json:"sfixed64_value,omitempty"`
Expand Down
14 changes: 14 additions & 0 deletions examples/clients/abe/message_path_enum_nested_path_enum.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/*
* A Bit of Everything
*
* No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
*
* OpenAPI spec version: 1.0
* Contact: none@example.com
* Generated by: https://github.com/swagger-api/swagger-codegen.git
*/

package abe

type MessagePathEnumNestedPathEnum struct {
}
14 changes: 14 additions & 0 deletions examples/clients/abe/pathenum_path_enum.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/*
* A Bit of Everything
*
* No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
*
* OpenAPI spec version: 1.0
* Contact: none@example.com
* Generated by: https://github.com/swagger-api/swagger-codegen.git
*/

package abe

type PathenumPathEnum struct {
}
1 change: 1 addition & 0 deletions examples/integration/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ go_test(
"//examples/clients/unannotatedecho:go_default_library",
"//examples/gateway:go_default_library",
"//examples/proto/examplepb:go_default_library",
"//examples/proto/pathenum:go_default_library",
"//examples/proto/sub:go_default_library",
"//examples/server:go_default_library",
"//runtime:go_default_library",
Expand Down
9 changes: 9 additions & 0 deletions examples/integration/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,9 @@ func testABEClientCreate(t *testing.T, cl *abe.ABitOfEverythingServiceApi) {
Sint32Value: 2147483647,
Sint64Value: "4611686018427387903",
NonConventionalNameValue: "camelCase",
EnumValue: abe.ExamplepbNumericEnum{},
PathEnumValue: abe.PathenumPathEnum{},
NestedPathEnumValue: abe.MessagePathEnumNestedPathEnum{},
}
resp, _, err := cl.Create(
want.FloatValue,
Expand All @@ -90,6 +93,9 @@ func testABEClientCreate(t *testing.T, cl *abe.ABitOfEverythingServiceApi) {
want.Sint32Value,
want.Sint64Value,
want.NonConventionalNameValue,
want.EnumValue.String(),
want.PathEnumValue.String(),
want.NestedPathEnumValue.String(),
)
if err != nil {
t.Errorf("cl.Create(%#v) failed with %v; want success", want, err)
Expand Down Expand Up @@ -123,6 +129,9 @@ func testABEClientCreateBody(t *testing.T, cl *abe.ABitOfEverythingServiceApi) {
Sint32Value: 2147483647,
Sint64Value: "4611686018427387903",
NonConventionalNameValue: "camelCase",
EnumValue: abe.ExamplepbNumericEnum{},
PathEnumValue: abe.PathenumPathEnum{},
NestedPathEnumValue: abe.MessagePathEnumNestedPathEnum{},

Nested: []abe.ABitOfEverythingNested{
{
Expand Down
12 changes: 11 additions & 1 deletion examples/integration/integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
"github.com/golang/protobuf/proto"
"github.com/golang/protobuf/ptypes/empty"
gw "github.com/grpc-ecosystem/grpc-gateway/examples/proto/examplepb"
"github.com/grpc-ecosystem/grpc-gateway/examples/proto/pathenum"
"github.com/grpc-ecosystem/grpc-gateway/examples/proto/sub"
"github.com/grpc-ecosystem/grpc-gateway/runtime"
"google.golang.org/grpc/codes"
Expand Down Expand Up @@ -284,8 +285,11 @@ func testABECreate(t *testing.T, port int) {
Sint32Value: 2147483647,
Sint64Value: 4611686018427387903,
NonConventionalNameValue: "camelCase",
EnumValue: gw.NumericEnum_ZERO,
PathEnumValue: pathenum.PathEnum_DEF,
NestedPathEnumValue: pathenum.MessagePathEnum_JKL,
}
url := fmt.Sprintf("http://localhost:%d/v1/example/a_bit_of_everything/%f/%f/%d/separator/%d/%d/%d/%d/%v/%s/%d/%d/%d/%d/%d/%s", port, want.FloatValue, want.DoubleValue, want.Int64Value, want.Uint64Value, want.Int32Value, want.Fixed64Value, want.Fixed32Value, want.BoolValue, want.StringValue, want.Uint32Value, want.Sfixed32Value, want.Sfixed64Value, want.Sint32Value, want.Sint64Value, want.NonConventionalNameValue)
url := fmt.Sprintf("http://localhost:%d/v1/example/a_bit_of_everything/%f/%f/%d/separator/%d/%d/%d/%d/%v/%s/%d/%d/%d/%d/%d/%s/%s/%s/%s", port, want.FloatValue, want.DoubleValue, want.Int64Value, want.Uint64Value, want.Int32Value, want.Fixed64Value, want.Fixed32Value, want.BoolValue, want.StringValue, want.Uint32Value, want.Sfixed32Value, want.Sfixed64Value, want.Sint32Value, want.Sint64Value, want.NonConventionalNameValue, want.EnumValue, want.PathEnumValue, want.NestedPathEnumValue)

resp, err := http.Post(url, "application/json", strings.NewReader("{}"))
if err != nil {
Expand Down Expand Up @@ -335,6 +339,9 @@ func testABECreateBody(t *testing.T, port int) {
Sint32Value: 2147483647,
Sint64Value: 4611686018427387903,
NonConventionalNameValue: "camelCase",
EnumValue: gw.NumericEnum_ONE,
PathEnumValue: pathenum.PathEnum_ABC,
NestedPathEnumValue: pathenum.MessagePathEnum_GHI,

Nested: []*gw.ABitOfEverything_Nested{
{
Expand Down Expand Up @@ -429,6 +436,9 @@ func testABEBulkCreate(t *testing.T, port int) {
Sint32Value: 2147483647,
Sint64Value: 4611686018427387903,
NonConventionalNameValue: "camelCase",
EnumValue: gw.NumericEnum_ONE,
PathEnumValue: pathenum.PathEnum_ABC,
NestedPathEnumValue: pathenum.MessagePathEnum_GHI,

Nested: []*gw.ABitOfEverything_Nested{
{
Expand Down
2 changes: 2 additions & 0 deletions examples/proto/examplepb/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ proto_library(
"response_body_service.proto",
],
deps = [
"//examples/proto/pathenum:pathenum_proto",
"//examples/proto/sub:sub_proto",
"//examples/proto/sub2:sub2_proto",
"//protoc-gen-swagger/options:options_proto",
Expand All @@ -43,6 +44,7 @@ go_proto_library(
importpath = "github.com/grpc-ecosystem/grpc-gateway/examples/proto/examplepb",
proto = ":examplepb_proto",
deps = [
"//examples/proto/pathenum:go_default_library",
"//examples/proto/sub:go_default_library",
"//examples/proto/sub2:go_default_library",
"//protoc-gen-swagger/options:go_default_library",
Expand Down
Loading

0 comments on commit 7cf77b0

Please sign in to comment.