Repository: goadesign/goa
Pull request #3402 (2023-10-25 11:44:41)

Fix struct:field:name Meta to work for HTTP payloads
* As expected, 01c71df1e8cd3042c132e289965a08f12c3e456b failed.
* 7cbe2d63b0e06b3409e704796044bc0360e83e69 fixes it.

raphael: This is great, thank you!

Patch:
diff --git a/http/codegen/service_data.go b/http/codegen/service_data.go
index 01447860..ef30b5b6 100644
--- a/http/codegen/service_data.go
+++ b/http/codegen/service_data.go
@@ -2299,7 +2299,7 @@ func extractPathParams(a *expr.MappedAttributeExpr, service *expr.AttributeExpr,
 
 			fptr bool
 		)
-		fieldName := codegen.Goify(name, true)
+		fieldName := codegen.GoifyAtt(c, name, true)
 		if !expr.IsObject(service.Type) {
 			fieldName = ""
 		} else {
@@ -2363,7 +2363,7 @@ func extractQueryParams(a *expr.MappedAttributeExpr, service *expr.AttributeExpr
 		if pointer {
 			typeRef = "*" + typeRef
 		}
-		fieldName := codegen.Goify(name, true)
+		fieldName := codegen.GoifyAtt(c, name, true)
 		if !expr.IsObject(service.Type) {
 			fieldName = ""
 		} else {
@@ -2435,7 +2435,7 @@ func extractHeaders(a *expr.MappedAttributeExpr, svcAtt *expr.AttributeExpr, svc
 		{
 			pointer = a.IsPrimitivePointer(name, true)
 			if expr.IsObject(svcAtt.Type) {
-				fieldName = codegen.Goify(name, true)
+				fieldName = codegen.GoifyAtt(attr, name, true)
 				fptr = svcCtx.IsPrimitivePointer(name, svcAtt)
 			}
 			if pointer {
@@ -2494,7 +2494,7 @@ func extractCookies(a *expr.MappedAttributeExpr, svcAtt *expr.AttributeExpr, svc
 		{
 			pointer = a.IsPrimitivePointer(name, true)
 			if expr.IsObject(svcAtt.Type) {
-				fieldName = codegen.Goify(name, true)
+				fieldName = codegen.GoifyAtt(hattr, name, true)
 				fptr = svcCtx.IsPrimitivePointer(name, svcAtt)
 				ft = svcAtt.Find(name).Type
 			}


Test patch:
diff --git a/http/codegen/client_body_types_test.go b/http/codegen/client_body_types_test.go
index 6c2bc64f..dd6ade44 100644
--- a/http/codegen/client_body_types_test.go
+++ b/http/codegen/client_body_types_test.go
@@ -77,7 +77,14 @@ func TestClientTypes(t *testing.T) {
 		{"client-payload-extend-validate", testdata.PayloadExtendedValidateDSL, PayloadExtendedValidateClientTypesFile},
 		{"client-result-type-validate", testdata.ResultTypeValidateDSL, ResultTypeValidateClientTypesFile},
 		{"client-with-result-collection", testdata.ResultWithResultCollectionDSL, WithResultCollectionClientTypesFile},
+		{"client-with-result-view", testdata.ResultWithResultViewDSL, ResultWithResultViewClientTypesFile},
 		{"client-empty-error-response-body", testdata.EmptyErrorResponseBodyDSL, EmptyErrorResponseBodyClientTypesFile},
+		{"client-with-error-custom-pkg", testdata.WithErrorCustomPkgDSL, WithErrorCustomPkgClientTypesFile},
+		{"client-body-custom-name", testdata.PayloadBodyCustomNameDSL, BodyCustomNameClientTypesFile},
+		{"client-path-custom-name", testdata.PayloadPathCustomNameDSL, ""},
+		{"client-query-custom-name", testdata.PayloadQueryCustomNameDSL, ""},
+		{"client-header-custom-name", testdata.PayloadHeaderCustomNameDSL, ""},
+		{"client-cookie-custom-name", testdata.PayloadCookieCustomNameDSL, ""},
 	}
 	for _, c := range cases {
 		t.Run(c.Name, func(t *testing.T) {
@@ -711,6 +718,34 @@ func ValidateRtResponseBody(body *RtResponseBody) (err error) {
 }
 `
 
+const ResultWithResultViewClientTypesFile = `// MethodResultWithResultViewResponseBody is the type of the
+// "ServiceResultWithResultView" service "MethodResultWithResultView" endpoint
+// HTTP response body.
+type MethodResultWithResultViewResponseBody struct {
+	Name *string         ` + "`" + `form:"name,omitempty" json:"name,omitempty" xml:"name,omitempty"` + "`" + `
+	Rt   *RtResponseBody ` + "`" + `form:"rt,omitempty" json:"rt,omitempty" xml:"rt,omitempty"` + "`" + `
+}
+
+// RtResponseBody is used to define fields on response body types.
+type RtResponseBody struct {
+	X *string ` + "`" + `form:"x,omitempty" json:"x,omitempty" xml:"x,omitempty"` + "`" + `
+}
+
+// NewMethodResultWithResultViewResulttypeOK builds a
+// "ServiceResultWithResultView" service "MethodResultWithResultView" endpoint
+// result from a HTTP "OK" response.
+func NewMethodResultWithResultViewResulttypeOK(body *MethodResultWithResultViewResponseBody) *serviceresultwithresultviewviews.ResulttypeView {
+	v := &serviceresultwithresultviewviews.ResulttypeView{
+		Name: body.Name,
+	}
+	if body.Rt != nil {
+		v.Rt = unmarshalRtResponseBodyToServiceresultwithresultviewviewsRtView(body.Rt)
+	}
+
+	return v
+}
+`
+
 const EmptyErrorResponseBodyClientTypesFile = `// NewMethodEmptyErrorResponseBodyInternalError builds a
 // ServiceEmptyErrorResponseBody service MethodEmptyErrorResponseBody endpoint
 // internal_error error.
@@ -735,3 +770,46 @@ func NewMethodEmptyErrorResponseBodyNotFound(inHeader string) serviceemptyerrorr
 	return v
 }
 `
+const WithErrorCustomPkgClientTypesFile = `// MethodWithErrorCustomPkgErrorNameResponseBody is the type of the
+// "ServiceWithErrorCustomPkg" service "MethodWithErrorCustomPkg" endpoint HTTP
+// response body for the "error_name" error.
+type MethodWithErrorCustomPkgErrorNameResponseBody struct {
+	Name *string ` + "`" + `form:"name,omitempty" json:"name,omitempty" xml:"name,omitempty"` + "`" + `
+}
+
+// NewMethodWithErrorCustomPkgErrorName builds a ServiceWithErrorCustomPkg
+// service MethodWithErrorCustomPkg endpoint error_name error.
+func NewMethodWithErrorCustomPkgErrorName(body *MethodWithErrorCustomPkgErrorNameResponseBody) *custom.CustomError {
+	v := &custom.CustomError{
+		Name: *body.Name,
+	}
+
+	return v
+}
+
+// ValidateMethodWithErrorCustomPkgErrorNameResponseBody runs the validations
+// defined on MethodWithErrorCustomPkg_error_name_Response_Body
+func ValidateMethodWithErrorCustomPkgErrorNameResponseBody(body *MethodWithErrorCustomPkgErrorNameResponseBody) (err error) {
+	if body.Name == nil {
+		err = goa.MergeErrors(err, goa.MissingFieldError("name", "body"))
+	}
+	return
+}
+`
+
+const BodyCustomNameClientTypesFile = `// MethodBodyCustomNameRequestBody is the type of the "ServiceBodyCustomName"
+// service "MethodBodyCustomName" endpoint HTTP request body.
+type MethodBodyCustomNameRequestBody struct {
+	Body *string ` + "`" + `form:"b,omitempty" json:"b,omitempty" xml:"b,omitempty"` + "`" + `
+}
+
+// NewMethodBodyCustomNameRequestBody builds the HTTP request body from the
+// payload of the "MethodBodyCustomName" endpoint of the
+// "ServiceBodyCustomName" service.
+func NewMethodBodyCustomNameRequestBody(p *servicebodycustomname.MethodBodyCustomNamePayload) *MethodBodyCustomNameRequestBody {
+	body := &MethodBodyCustomNameRequestBody{
+		Body: p.Body,
+	}
+	return body
+}
+`
diff --git a/http/codegen/client_cli_test.go b/http/codegen/client_cli_test.go
index 101934b9..dfc8aa06 100644
--- a/http/codegen/client_cli_test.go
+++ b/http/codegen/client_cli_test.go
@@ -42,6 +42,11 @@ func TestClientCLIFiles(t *testing.T) {
 		{"map-query-object", testdata.PayloadMapQueryObjectDSL, testdata.MapQueryObjectBuildCode, 1, 1},
 		{"empty-body-build", testdata.PayloadBodyPrimitiveFieldEmptyDSL, testdata.EmptyBodyBuildCode, 1, 1},
 		{"with-params-and-headers-dsl", testdata.WithParamsAndHeadersBlockDSL, testdata.WithParamsAndHeadersBlockBuildCode, 1, 1},
+		{"body-custom-name", testdata.PayloadBodyCustomNameDSL, testdata.PayloadBodyCustomNameBuildCode, 1, 1},
+		{"path-custom-name", testdata.PayloadPathCustomNameDSL, testdata.PayloadPathCustomNameBuildCode, 1, 1},
+		{"query-custom-name", testdata.PayloadQueryCustomNameDSL, testdata.PayloadQueryCustomNameBuildCode, 1, 1},
+		{"header-custom-name", testdata.PayloadHeaderCustomNameDSL, testdata.PayloadHeaderCustomNameBuildCode, 1, 1},
+		{"cookie-custom-name", testdata.PayloadCookieCustomNameDSL, testdata.PayloadCookieCustomNameBuildCode, 1, 1},
 	}
 
 	for _, c := range cases {
diff --git a/http/codegen/client_encode_test.go b/http/codegen/client_encode_test.go
index 45e445e3..5edb2917 100644
--- a/http/codegen/client_encode_test.go
+++ b/http/codegen/client_encode_test.go
@@ -169,6 +169,12 @@ func TestClientEncode(t *testing.T) {
 		{"query-map-alias", testdata.QueryMapAliasDSL, testdata.QueryMapAliasEncodeCode},
 		{"query-map-alias-validate", testdata.QueryMapAliasValidateDSL, testdata.QueryMapAliasValidateEncodeCode},
 		{"query-array-nested-alias-validate", testdata.QueryArrayNestedAliasValidateDSL, testdata.QueryArrayNestedAliasValidateEncodeCode},
+
+		{"body-custom-name", testdata.PayloadBodyCustomNameDSL, testdata.PayloadBodyCustomNameEncodeCode},
+		// path-custom-name is not needed because no encoder is created.
+		{"query-custom-name", testdata.PayloadQueryCustomNameDSL, testdata.PayloadQueryCustomNameEncodeCode},
+		{"header-custom-name", testdata.PayloadHeaderCustomNameDSL, testdata.PayloadHeaderCustomNameEncodeCode},
+		{"cookie-custom-name", testdata.PayloadCookieCustomNameDSL, testdata.PayloadCookieCustomNameEncodeCode},
 	}
 	golden := makeGolden(t, "testdata/payload_encode_functions.go")
 	if golden != nil {
diff --git a/http/codegen/server_decode_test.go b/http/codegen/server_decode_test.go
index 1dab4e03..7c9f427c 100644
--- a/http/codegen/server_decode_test.go
+++ b/http/codegen/server_decode_test.go
@@ -206,6 +206,12 @@ func TestDecode(t *testing.T) {
 		{"decode-query-array-nested-alias-validate", testdata.QueryArrayNestedAliasValidateDSL, testdata.QueryArrayNestedAliasValidateDecodeCode},
 		{"decode-header-int-alias", testdata.HeaderIntAliasDSL, testdata.HeaderIntAliasDecodeCode},
 		{"decode-path-int-alias", testdata.PathIntAliasDSL, testdata.PathIntAliasDecodeCode},
+
+		{"decode-body-custom-name", testdata.PayloadBodyCustomNameDSL, testdata.PayloadBodyCustomNameDecodeCode},
+		{"decode-path-custom-name", testdata.PayloadPathCustomNameDSL, testdata.PayloadPathCustomNameDecodeCode},
+		{"decode-query-custom-name", testdata.PayloadQueryCustomNameDSL, testdata.PayloadQueryCustomNameDecodeCode},
+		{"decode-header-custom-name", testdata.PayloadHeaderCustomNameDSL, testdata.PayloadHeaderCustomNameDecodeCode},
+		{"decode-cookie-custom-name", testdata.PayloadCookieCustomNameDSL, testdata.PayloadCookieCustomNameDecodeCode},
 	}
 	golden := makeGolden(t, "testdata/payload_decode_functions.go")
 	if golden != nil {
diff --git a/http/codegen/server_types_test.go b/http/codegen/server_types_test.go
index 20b5c4de..c4e8f3e5 100644
--- a/http/codegen/server_types_test.go
+++ b/http/codegen/server_types_test.go
@@ -24,6 +24,11 @@ func TestServerTypes(t *testing.T) {
 		{"server-with-result-view", testdata.ResultWithResultViewDSL, ResultWithResultViewServerTypesFile},
 		{"server-empty-error-response-body", testdata.EmptyErrorResponseBodyDSL, ""},
 		{"server-with-error-custom-pkg", testdata.WithErrorCustomPkgDSL, WithErrorCustomPkgServerTypesFile},
+		{"server-body-custom-name", testdata.PayloadBodyCustomNameDSL, BodyCustomNameServerTypesFile},
+		{"server-path-custom-name", testdata.PayloadPathCustomNameDSL, PathCustomNameServerTypesFile},
+		{"server-query-custom-name", testdata.PayloadQueryCustomNameDSL, QueryCustomNameServerTypesFile},
+		{"server-header-custom-name", testdata.PayloadHeaderCustomNameDSL, HeaderCustomNameServerTypesFile},
+		{"server-cookie-custom-name", testdata.PayloadCookieCustomNameDSL, CookieCustomNameServerTypesFile},
 	}
 	for _, c := range cases {
 		t.Run(c.Name, func(t *testing.T) {
@@ -321,3 +326,58 @@ func NewMethodWithErrorCustomPkgErrorNameResponseBody(res *custom.CustomError) *
 	return body
 }
 `
+
+const BodyCustomNameServerTypesFile = `// MethodBodyCustomNameRequestBody is the type of the "ServiceBodyCustomName"
+// service "MethodBodyCustomName" endpoint HTTP request body.
+type MethodBodyCustomNameRequestBody struct {
+	Body *string ` + "`" + `form:"b,omitempty" json:"b,omitempty" xml:"b,omitempty"` + "`" + `
+}
+
+// NewMethodBodyCustomNamePayload builds a ServiceBodyCustomName service
+// MethodBodyCustomName endpoint payload.
+func NewMethodBodyCustomNamePayload(body *MethodBodyCustomNameRequestBody) *servicebodycustomname.MethodBodyCustomNamePayload {
+	v := &servicebodycustomname.MethodBodyCustomNamePayload{
+		Body: body.Body,
+	}
+
+	return v
+}
+`
+const PathCustomNameServerTypesFile = `// NewMethodPathCustomNamePayload builds a ServicePathCustomName service
+// MethodPathCustomName endpoint payload.
+func NewMethodPathCustomNamePayload(p string) *servicepathcustomname.MethodPathCustomNamePayload {
+	v := &servicepathcustomname.MethodPathCustomNamePayload{}
+	v.Path = p
+
+	return v
+}
+`
+const QueryCustomNameServerTypesFile = `// NewMethodQueryCustomNamePayload builds a ServiceQueryCustomName service
+// MethodQueryCustomName endpoint payload.
+func NewMethodQueryCustomNamePayload(q *string) *servicequerycustomname.MethodQueryCustomNamePayload {
+	v := &servicequerycustomname.MethodQueryCustomNamePayload{}
+	v.Query = q
+
+	return v
+}
+`
+
+const HeaderCustomNameServerTypesFile = `// NewMethodHeaderCustomNamePayload builds a ServiceHeaderCustomName service
+// MethodHeaderCustomName endpoint payload.
+func NewMethodHeaderCustomNamePayload(h *string) *serviceheadercustomname.MethodHeaderCustomNamePayload {
+	v := &serviceheadercustomname.MethodHeaderCustomNamePayload{}
+	v.Header = h
+
+	return v
+}
+`
+
+const CookieCustomNameServerTypesFile = `// NewMethodCookieCustomNamePayload builds a ServiceCookieCustomName service
+// MethodCookieCustomName endpoint payload.
+func NewMethodCookieCustomNamePayload(c2 *string) *servicecookiecustomname.MethodCookieCustomNamePayload {
+	v := &servicecookiecustomname.MethodCookieCustomNamePayload{}
+	v.Cookie = c2
+
+	return v
+}
+`
diff --git a/http/codegen/testdata/parse_endpoint_functions.go b/http/codegen/testdata/parse_endpoint_functions.go
index 9ba8ee7e..0a5c6c0c 100644
--- a/http/codegen/testdata/parse_endpoint_functions.go
+++ b/http/codegen/testdata/parse_endpoint_functions.go
@@ -1374,3 +1374,84 @@ func BuildMethodAPayload(serviceWithParamsAndHeadersBlockMethodABody string, ser
 	return v, nil
 }
 `
+
+var PayloadBodyCustomNameBuildCode = `// BuildMethodBodyCustomNamePayload builds the payload for the
+// ServiceBodyCustomName MethodBodyCustomName endpoint from CLI flags.
+func BuildMethodBodyCustomNamePayload(serviceBodyCustomNameMethodBodyCustomNameBody string) (*servicebodycustomname.MethodBodyCustomNamePayload, error) {
+	var err error
+	var body MethodBodyCustomNameRequestBody
+	{
+		err = json.Unmarshal([]byte(serviceBodyCustomNameMethodBodyCustomNameBody), &body)
+		if err != nil {
+			return nil, fmt.Errorf("invalid JSON for body, \nerror: %s, \nexample of valid JSON:\n%s", err, "'{\n      \"b\": \"Doloribus qui quia.\"\n   }'")
+		}
+	}
+	v := &servicebodycustomname.MethodBodyCustomNamePayload{
+		Body: body.Body,
+	}
+
+	return v, nil
+}
+`
+
+var PayloadPathCustomNameBuildCode = `// BuildMethodPathCustomNamePayload builds the payload for the
+// ServicePathCustomName MethodPathCustomName endpoint from CLI flags.
+func BuildMethodPathCustomNamePayload(servicePathCustomNameMethodPathCustomNameP string) (*servicepathcustomname.MethodPathCustomNamePayload, error) {
+	var p string
+	{
+		p = servicePathCustomNameMethodPathCustomNameP
+	}
+	v := &servicepathcustomname.MethodPathCustomNamePayload{}
+	v.Path = p
+
+	return v, nil
+}
+`
+
+var PayloadQueryCustomNameBuildCode = `// BuildMethodQueryCustomNamePayload builds the payload for the
+// ServiceQueryCustomName MethodQueryCustomName endpoint from CLI flags.
+func BuildMethodQueryCustomNamePayload(serviceQueryCustomNameMethodQueryCustomNameQ string) (*servicequerycustomname.MethodQueryCustomNamePayload, error) {
+	var q *string
+	{
+		if serviceQueryCustomNameMethodQueryCustomNameQ != "" {
+			q = &serviceQueryCustomNameMethodQueryCustomNameQ
+		}
+	}
+	v := &servicequerycustomname.MethodQueryCustomNamePayload{}
+	v.Query = q
+
+	return v, nil
+}
+`
+
+var PayloadHeaderCustomNameBuildCode = `// BuildMethodHeaderCustomNamePayload builds the payload for the
+// ServiceHeaderCustomName MethodHeaderCustomName endpoint from CLI flags.
+func BuildMethodHeaderCustomNamePayload(serviceHeaderCustomNameMethodHeaderCustomNameH string) (*serviceheadercustomname.MethodHeaderCustomNamePayload, error) {
+	var h *string
+	{
+		if serviceHeaderCustomNameMethodHeaderCustomNameH != "" {
+			h = &serviceHeaderCustomNameMethodHeaderCustomNameH
+		}
+	}
+	v := &serviceheadercustomname.MethodHeaderCustomNamePayload{}
+	v.Header = h
+
+	return v, nil
+}
+`
+
+var PayloadCookieCustomNameBuildCode = `// BuildMethodCookieCustomNamePayload builds the payload for the
+// ServiceCookieCustomName MethodCookieCustomName endpoint from CLI flags.
+func BuildMethodCookieCustomNamePayload(serviceCookieCustomNameMethodCookieCustomNameC2 string) (*servicecookiecustomname.MethodCookieCustomNamePayload, error) {
+	var c2 *string
+	{
+		if serviceCookieCustomNameMethodCookieCustomNameC2 != "" {
+			c2 = &serviceCookieCustomNameMethodCookieCustomNameC2
+		}
+	}
+	v := &servicecookiecustomname.MethodCookieCustomNamePayload{}
+	v.Cookie = c2
+
+	return v, nil
+}
+`
diff --git a/http/codegen/testdata/payload_decode_functions.go b/http/codegen/testdata/payload_decode_functions.go
index 72ba9425..19e3be6c 100644
--- a/http/codegen/testdata/payload_decode_functions.go
+++ b/http/codegen/testdata/payload_decode_functions.go
@@ -5717,3 +5717,101 @@ func DecodeMethodPathCustomUInt64Request(mux goahttp.Muxer, decoder func(*http.R
 	}
 }
 `
+
+var PayloadBodyCustomNameDecodeCode = `// DecodeMethodBodyCustomNameRequest returns a decoder for requests sent to the
+// ServiceBodyCustomName MethodBodyCustomName endpoint.
+func DecodeMethodBodyCustomNameRequest(mux goahttp.Muxer, decoder func(*http.Request) goahttp.Decoder) func(*http.Request) (any, error) {
+	return func(r *http.Request) (any, error) {
+		var (
+			body MethodBodyCustomNameRequestBody
+			err  error
+		)
+		err = decoder(r).Decode(&body)
+		if err != nil {
+			if err == io.EOF {
+				return nil, goa.MissingPayloadError()
+			}
+			return nil, goa.DecodePayloadError(err.Error())
+		}
+		payload := NewMethodBodyCustomNamePayload(&body)
+
+		return payload, nil
+	}
+}
+`
+
+var PayloadPathCustomNameDecodeCode = `// DecodeMethodPathCustomNameRequest returns a decoder for requests sent to the
+// ServicePathCustomName MethodPathCustomName endpoint.
+func DecodeMethodPathCustomNameRequest(mux goahttp.Muxer, decoder func(*http.Request) goahttp.Decoder) func(*http.Request) (any, error) {
+	return func(r *http.Request) (any, error) {
+		var (
+			p string
+
+			params = mux.Vars(r)
+		)
+		p = params["p"]
+		payload := NewMethodPathCustomNamePayload(p)
+
+		return payload, nil
+	}
+}
+`
+
+var PayloadQueryCustomNameDecodeCode = `// DecodeMethodQueryCustomNameRequest returns a decoder for requests sent to
+// the ServiceQueryCustomName MethodQueryCustomName endpoint.
+func DecodeMethodQueryCustomNameRequest(mux goahttp.Muxer, decoder func(*http.Request) goahttp.Decoder) func(*http.Request) (any, error) {
+	return func(r *http.Request) (any, error) {
+		var (
+			q *string
+		)
+		qRaw := r.URL.Query().Get("q")
+		if qRaw != "" {
+			q = &qRaw
+		}
+		payload := NewMethodQueryCustomNamePayload(q)
+
+		return payload, nil
+	}
+}
+`
+
+var PayloadHeaderCustomNameDecodeCode = `// DecodeMethodHeaderCustomNameRequest returns a decoder for requests sent to
+// the ServiceHeaderCustomName MethodHeaderCustomName endpoint.
+func DecodeMethodHeaderCustomNameRequest(mux goahttp.Muxer, decoder func(*http.Request) goahttp.Decoder) func(*http.Request) (any, error) {
+	return func(r *http.Request) (any, error) {
+		var (
+			h *string
+		)
+		hRaw := r.Header.Get("h")
+		if hRaw != "" {
+			h = &hRaw
+		}
+		payload := NewMethodHeaderCustomNamePayload(h)
+
+		return payload, nil
+	}
+}
+`
+
+var PayloadCookieCustomNameDecodeCode = `// DecodeMethodCookieCustomNameRequest returns a decoder for requests sent to
+// the ServiceCookieCustomName MethodCookieCustomName endpoint.
+func DecodeMethodCookieCustomNameRequest(mux goahttp.Muxer, decoder func(*http.Request) goahttp.Decoder) func(*http.Request) (any, error) {
+	return func(r *http.Request) (any, error) {
+		var (
+			c2 *string
+			c  *http.Cookie
+		)
+		c, _ = r.Cookie("c")
+		var c2Raw string
+		if c != nil {
+			c2Raw = c.Value
+		}
+		if c2Raw != "" {
+			c2 = &c2Raw
+		}
+		payload := NewMethodCookieCustomNamePayload(c2)
+
+		return payload, nil
+	}
+}
+`
diff --git a/http/codegen/testdata/payload_dsls.go b/http/codegen/testdata/payload_dsls.go
index 72622b52..dfaa4c34 100644
--- a/http/codegen/testdata/payload_dsls.go
+++ b/http/codegen/testdata/payload_dsls.go
@@ -3500,3 +3500,86 @@ var PayloadPathCustomUInt64DSL = func() {
 		})
 	})
 }
+
+var PayloadBodyCustomNameDSL = func() {
+	Service("ServiceBodyCustomName", func() {
+		Method("MethodBodyCustomName", func() {
+			Payload(func() {
+				Attribute("b", String, func() {
+					Meta("struct:field:name", "Body")
+				})
+			})
+			HTTP(func() {
+				GET("/")
+			})
+		})
+	})
+}
+
+var PayloadPathCustomNameDSL = func() {
+	Service("ServicePathCustomName", func() {
+		Method("MethodPathCustomName", func() {
+			Payload(func() {
+				Attribute("p", String, func() {
+					Meta("struct:field:name", "Path")
+				})
+				Required("p")
+			})
+			HTTP(func() {
+				GET("/{p}")
+			})
+		})
+	})
+}
+
+var PayloadQueryCustomNameDSL = func() {
+	Service("ServiceQueryCustomName", func() {
+		Method("MethodQueryCustomName", func() {
+			Payload(func() {
+				Attribute("q", String, func() {
+					Meta("struct:field:name", "Query")
+				})
+			})
+			HTTP(func() {
+				GET("/")
+				Params(func() {
+					Param("q")
+				})
+			})
+		})
+	})
+}
+
+var PayloadHeaderCustomNameDSL = func() {
+	Service("ServiceHeaderCustomName", func() {
+		Method("MethodHeaderCustomName", func() {
+			Payload(func() {
+				Attribute("h", String, func() {
+					Meta("struct:field:name", "Header")
+				})
+			})
+			HTTP(func() {
+				GET("/")
+				Headers(func() {
+					Header("h")
+				})
+			})
+		})
+	})
+}
+
+var PayloadCookieCustomNameDSL = func() {
+	Service("ServiceCookieCustomName", func() {
+		Method("MethodCookieCustomName", func() {
+			Payload(func() {
+				Attribute("c", String, func() {
+					Meta("struct:field:name", "Cookie")
+				})
+			})
+			HTTP(func() {
+				GET("/")
+				Cookie("c")
+			})
+		})
+	})
+}
diff --git a/http/codegen/testdata/payload_encode_functions.go b/http/codegen/testdata/payload_encode_functions.go
index af804215..30470e60 100644
--- a/http/codegen/testdata/payload_encode_functions.go
+++ b/http/codegen/testdata/payload_encode_functions.go
@@ -2613,3 +2613,75 @@ func EncodeMethodARequest(encoder func(*http.Request) goahttp.Encoder) func(*htt
 	}
 }
 `
+
+var PayloadBodyCustomNameEncodeCode = `// EncodeMethodBodyCustomNameRequest returns an encoder for requests sent to
+// the ServiceBodyCustomName MethodBodyCustomName server.
+func EncodeMethodBodyCustomNameRequest(encoder func(*http.Request) goahttp.Encoder) func(*http.Request, any) error {
+	return func(req *http.Request, v any) error {
+		p, ok := v.(*servicebodycustomname.MethodBodyCustomNamePayload)
+		if !ok {
+			return goahttp.ErrInvalidType("ServiceBodyCustomName", "MethodBodyCustomName", "*servicebodycustomname.MethodBodyCustomNamePayload", v)
+		}
+		body := NewMethodBodyCustomNameRequestBody(p)
+		if err := encoder(req).Encode(&body); err != nil {
+			return goahttp.ErrEncodingError("ServiceBodyCustomName", "MethodBodyCustomName", err)
+		}
+		return nil
+	}
+}
+`
+
+var PayloadQueryCustomNameEncodeCode = `// EncodeMethodQueryCustomNameRequest returns an encoder for requests sent to
+// the ServiceQueryCustomName MethodQueryCustomName server.
+func EncodeMethodQueryCustomNameRequest(encoder func(*http.Request) goahttp.Encoder) func(*http.Request, any) error {
+	return func(req *http.Request, v any) error {
+		p, ok := v.(*servicequerycustomname.MethodQueryCustomNamePayload)
+		if !ok {
+			return goahttp.ErrInvalidType("ServiceQueryCustomName", "MethodQueryCustomName", "*servicequerycustomname.MethodQueryCustomNamePayload", v)
+		}
+		values := req.URL.Query()
+		if p.Query != nil {
+			values.Add("q", *p.Query)
+		}
+		req.URL.RawQuery = values.Encode()
+		return nil
+	}
+}
+`
+
+var PayloadHeaderCustomNameEncodeCode = `// EncodeMethodHeaderCustomNameRequest returns an encoder for requests sent to
+// the ServiceHeaderCustomName MethodHeaderCustomName server.
+func EncodeMethodHeaderCustomNameRequest(encoder func(*http.Request) goahttp.Encoder) func(*http.Request, any) error {
+	return func(req *http.Request, v any) error {
+		p, ok := v.(*serviceheadercustomname.MethodHeaderCustomNamePayload)
+		if !ok {
+			return goahttp.ErrInvalidType("ServiceHeaderCustomName", "MethodHeaderCustomName", "*serviceheadercustomname.MethodHeaderCustomNamePayload", v)
+		}
+		if p.Header != nil {
+			head := *p.Header
+			req.Header.Set("h", head)
+		}
+		return nil
+	}
+}
+`
+
+var PayloadCookieCustomNameEncodeCode = `// EncodeMethodCookieCustomNameRequest returns an encoder for requests sent to
+// the ServiceCookieCustomName MethodCookieCustomName server.
+func EncodeMethodCookieCustomNameRequest(encoder func(*http.Request) goahttp.Encoder) func(*http.Request, any) error {
+	return func(req *http.Request, v any) error {
+		p, ok := v.(*servicecookiecustomname.MethodCookieCustomNamePayload)
+		if !ok {
+			return goahttp.ErrInvalidType("ServiceCookieCustomName", "MethodCookieCustomName", "*servicecookiecustomname.MethodCookieCustomNamePayload", v)
+		}
+		if p.Cookie != nil {
+			v := *p.Cookie
+			req.AddCookie(&http.Cookie{
+				Name:  "c",
+				Value: v,
+			})
+		}
+		return nil
+	}
+}
+`