Repository: goadesign/goa
Pull request #3006 (2022-02-24 02:47:02)

Fix alias client query params


Patch:
diff --git a/http/codegen/service_data.go b/http/codegen/service_data.go
index 233ddd91..9aadb79d 100644
--- a/http/codegen/service_data.go
+++ b/http/codegen/service_data.go
@@ -2246,6 +2246,12 @@ func buildResponseBodyType(body, att *expr.AttributeExpr, e *expr.HTTPEndpointEx
 func extractPathParams(a *expr.MappedAttributeExpr, service *expr.AttributeExpr, scope *codegen.NameScope) []*ParamData {
 	var params []*ParamData
 	codegen.WalkMappedAttr(a, func(name, elem string, _ bool, c *expr.AttributeExpr) error {
+		// The StringSlice field of ParamData must be false for aliased primitive types
+		var stringSlice bool
+		if arr := expr.AsArray(c.Type); arr != nil {
+			stringSlice = arr.ElemType.Type.Kind() == expr.StringKind
+		}
+
 		makeHTTPType(c)
 		var (
 			varn = scope.Name(codegen.Goify(name, false))
@@ -2269,7 +2275,7 @@ func extractPathParams(a *expr.MappedAttributeExpr, service *expr.AttributeExpr,
 				Name:          elem,
 				AttributeName: name,
 				Slice:         arr != nil,
-				StringSlice:   arr != nil && arr.ElemType.Type.Kind() == expr.StringKind,
+				StringSlice:   stringSlice,
 				AttributeData: &AttributeData{
 					Description:  c.Description,
 					FieldName:    fieldName,
@@ -2296,6 +2302,12 @@ func extractPathParams(a *expr.MappedAttributeExpr, service *expr.AttributeExpr,
 func extractQueryParams(a *expr.MappedAttributeExpr, service *expr.AttributeExpr, scope *codegen.NameScope) []*ParamData {
 	var params []*ParamData
 	codegen.WalkMappedAttr(a, func(name, elem string, required bool, c *expr.AttributeExpr) error {
+		// The StringSlice field of ParamData must be false for aliased primitive types
+		var stringSlice bool
+		if arr := expr.AsArray(c.Type); arr != nil {
+			stringSlice = arr.ElemType.Type.Kind() == expr.StringKind
+		}
+
 		makeHTTPType(c)
 		var (
 			varn    = scope.Name(codegen.Goify(name, false))
@@ -2326,7 +2338,7 @@ func extractQueryParams(a *expr.MappedAttributeExpr, service *expr.AttributeExpr
 				expr.AsArray(mp.ElemType.Type).ElemType.Type.Kind() == expr.StringKind,
 			Element: &Element{
 				Slice:         arr != nil,
-				StringSlice:   arr != nil && arr.ElemType.Type.Kind() == expr.StringKind,
+				StringSlice:   stringSlice,
 				Name:          elem,
 				AttributeName: name,
 				AttributeData: &AttributeData{
@@ -2356,11 +2368,18 @@ func extractHeaders(a *expr.MappedAttributeExpr, svcAtt *expr.AttributeExpr, svc
 	var headers []*HeaderData
 	codegen.WalkMappedAttr(a, func(name, elem string, required bool, _ *expr.AttributeExpr) error {
 		var hattr *expr.AttributeExpr
+		var stringSlice bool
 		{
 			if hattr = svcAtt.Find(name); hattr == nil {
 				hattr = svcAtt
 			}
 			hattr = expr.DupAtt(hattr)
+
+			// The StringSlice field of ParamData must be false for aliased primitive types
+			if arr := expr.AsArray(hattr.Type); arr != nil {
+				stringSlice = arr.ElemType.Type.Kind() == expr.StringKind
+			}
+
 			makeHTTPType(hattr)
 		}
 		var (
@@ -2389,7 +2408,7 @@ func extractHeaders(a *expr.MappedAttributeExpr, svcAtt *expr.AttributeExpr, svc
 			Element: &Element{
 				Name:          elem,
 				Slice:         arr != nil,
-				StringSlice:   arr != nil && arr.ElemType.Type.Kind() == expr.StringKind,
+				StringSlice:   stringSlice,
 				AttributeName: name,
 				AttributeData: &AttributeData{
 					Description:  hattr.Description,


Test patch:
diff --git a/http/codegen/client_encode_test.go b/http/codegen/client_encode_test.go
index 2cdd7163..4231b5bc 100644
--- a/http/codegen/client_encode_test.go
+++ b/http/codegen/client_encode_test.go
@@ -63,6 +63,7 @@ func TestClientEncode(t *testing.T) {
 		{"query-array-bytes-validate", testdata.PayloadQueryArrayBytesValidateDSL, testdata.PayloadQueryArrayBytesValidateEncodeCode},
 		{"query-array-any", testdata.PayloadQueryArrayAnyDSL, testdata.PayloadQueryArrayAnyEncodeCode},
 		{"query-array-any-validate", testdata.PayloadQueryArrayAnyValidateDSL, testdata.PayloadQueryArrayAnyValidateEncodeCode},
+		{"query-array-alias", testdata.PayloadQueryArrayAliasDSL, testdata.PayloadQueryArrayAliasEncodeCode},
 		{"query-map-string-string", testdata.PayloadQueryMapStringStringDSL, testdata.PayloadQueryMapStringStringEncodeCode},
 		{"query-map-string-string-validate", testdata.PayloadQueryMapStringStringValidateDSL, testdata.PayloadQueryMapStringStringValidateEncodeCode},
 		{"query-map-string-bool", testdata.PayloadQueryMapStringBoolDSL, testdata.PayloadQueryMapStringBoolEncodeCode},
diff --git a/http/codegen/testdata/payload_dsls.go b/http/codegen/testdata/payload_dsls.go
index 1210f484..9e5d9f22 100644
--- a/http/codegen/testdata/payload_dsls.go
+++ b/http/codegen/testdata/payload_dsls.go
@@ -806,6 +806,21 @@ var PayloadQueryArrayAnyValidateDSL = func() {
 	})
 }
 
+var PayloadQueryArrayAliasDSL = func() {
+	var Alias = Type("Alias", String)
+	Service("ServiceQueryArrayAlias", func() {
+		Method("MethodQueryArrayAlias", func() {
+			Payload(func() {
+				Attribute("q", ArrayOf(Alias))
+			})
+			HTTP(func() {
+				GET("/")
+				Param("q")
+			})
+		})
+	})
+}
+
 var PayloadQueryMapStringStringDSL = func() {
 	Service("ServiceQueryMapStringString", func() {
 		Method("MethodQueryMapStringString", func() {
diff --git a/http/codegen/testdata/payload_encode_functions.go b/http/codegen/testdata/payload_encode_functions.go
index c5898341..b7663295 100644
--- a/http/codegen/testdata/payload_encode_functions.go
+++ b/http/codegen/testdata/payload_encode_functions.go
@@ -868,6 +868,25 @@ func EncodeMethodQueryArrayAnyValidateRequest(encoder func(*http.Request) goahtt
 }
 `
 
+var PayloadQueryArrayAliasEncodeCode = `// EncodeMethodQueryArrayAliasRequest returns an encoder for requests sent to
+// the ServiceQueryArrayAlias MethodQueryArrayAlias server.
+func EncodeMethodQueryArrayAliasRequest(encoder func(*http.Request) goahttp.Encoder) func(*http.Request, interface{}) error {
+	return func(req *http.Request, v interface{}) error {
+		p, ok := v.(*servicequeryarrayalias.MethodQueryArrayAliasPayload)
+		if !ok {
+			return goahttp.ErrInvalidType("ServiceQueryArrayAlias", "MethodQueryArrayAlias", "*servicequeryarrayalias.MethodQueryArrayAliasPayload", v)
+		}
+		values := req.URL.Query()
+		for _, value := range p.Q {
+			valueStr := string(value)
+			values.Add("q", valueStr)
+		}
+		req.URL.RawQuery = values.Encode()
+		return nil
+	}
+}
+`
+
 var PayloadQueryMapStringStringEncodeCode = `// EncodeMethodQueryMapStringStringRequest returns an encoder for requests sent
 // to the ServiceQueryMapStringString MethodQueryMapStringString server.
 func EncodeMethodQueryMapStringStringRequest(encoder func(*http.Request) goahttp.Encoder) func(*http.Request, interface{}) error {