Repository: goadesign/goa
Pull request #3450 (2024-01-15 18:32:51)

Properly handle MapParams
We can't directly reuse the code use for standard parameter mapping as it filters the query parameters keys.


Patch:
diff --git a/http/codegen/server.go b/http/codegen/server.go
index dafdd448..e8dc8707 100644
--- a/http/codegen/server.go
+++ b/http/codegen/server.go
@@ -778,8 +778,38 @@ const requestElementsT = `{{- define "request_elements" }}
 		{{- else if not .Required }}
 		if len({{ .VarName }}Raw) != 0 {
 		{{- end }}
+		if {{ .VarName }} == nil {
+			{{ .VarName }} = make({{ goTypeRef .Type }})
+		}
 		for keyRaw, valRaw := range {{ .VarName }}Raw {
-			{{- template "map_conversion" (mapQueryDecodeData .Type .VarName 0) }}
+			var key {{ goTypeRef .Type.KeyType.Type }}
+			{{- if eq .Type.KeyType.Type.Name "string" }}
+			key = keyRaw
+			{{- else }}
+				{{- template "type_conversion" (conversionData "key" "query" .Type.KeyType.Type) }}
+			{{- end }}
+			{{- if eq .Type.ElemType.Type.Name "string" }}
+				{{ .VarName }}[key] = valRaw[0]
+			{{- else if eq .Type.ElemType.Type.Name "array" }}
+				{{- if eq .Type.ElemType.Type.ElemType.Type.Name "string" }}
+					{{ .VarName }}[key] = valRaw
+				{{- else }}
+					var val {{ goTypeRef .Type.ElemType.Type }}
+					{
+						{{- template "slice_conversion" (conversionData "val" "query" .Type.ElemType.Type) }}
+					}
+					{{ .VarName }}[key] = val
+				{{- end }}
+			{{- else if eq .Type.ElemType.Type.Name "map" }}
+				{{- template "map_conversion" (mapQueryDecodeData .Type.ElemType.Type (printf "%s[key]" .VarName) 1) }}
+			{{- else }}
+				var val{{ .Loop }} {{ goTypeRef .Type.ElemType.Type }}
+				{
+					val{{ .Loop }}Raw := valRaw[0]
+					{{- template "type_conversion" (conversionData (printf "val%s" .Loop) "query" .Type.ElemType.Type) }}
+				}
+				{{ .VarName }}[key] = val{{ .Loop }}
+			{{- end }}
 		}
 		{{- if or .DefaultValue (not .Required) }}
 		}


Test patch:
diff --git a/http/codegen/testdata/payload_decode_functions.go b/http/codegen/testdata/payload_decode_functions.go
index a6dccb67..fb927e0b 100644
--- a/http/codegen/testdata/payload_decode_functions.go
+++ b/http/codegen/testdata/payload_decode_functions.go
@@ -4905,22 +4905,17 @@ func DecodeMethodMapQueryObjectRequest(mux goahttp.Muxer, decoder func(*http.Req
 			if len(cRaw) == 0 {
 				err = goa.MergeErrors(err, goa.MissingFieldError("c", "query string"))
 			}
+			if c == nil {
+				c = make(map[int][]string)
+			}
 			for keyRaw, valRaw := range cRaw {
-				if c == nil {
-					c = make(map[int][]string)
-				}
-				var keya int
-				{
-					openIdx := strings.IndexRune(keyRaw, '[')
-					closeIdx := strings.IndexRune(keyRaw, ']')
-					keyaRaw := keyRaw[openIdx+1 : closeIdx]
-					v, err2 := strconv.ParseInt(keyaRaw, 10, strconv.IntSize)
-					if err2 != nil {
-						err = goa.MergeErrors(err, goa.InvalidFieldTypeError("query", keyaRaw, "integer"))
-					}
-					keya = int(v)
+				var key int
+				v, err2 := strconv.ParseInt(keyRaw, 10, strconv.IntSize)
+				if err2 != nil {
+					err = goa.MergeErrors(err, goa.InvalidFieldTypeError("query", keyRaw, "integer"))
 				}
-				c[keya] = valRaw
+				key = int(v)
+				c[key] = valRaw
 			}
 		}
 		if err != nil {