Repository: goadesign/goa (go)

Issue:
v3: client/encode_decode.go has a type mismatch error
I was generating my code, and I am getting a weird type mismatch error.

in the `client/encode_decode.go` for a service, the `BuildUpdateRequest` tries to set a `*string` into a `string`

```go
func (c *Client) BuildUpdateRequest(ctx context.Context, v interface{}) (*http.Request, error) {
	var (
		id string
	)
	{
		p, ok := v.(*test.TestPayload)
		if !ok {
			return nil, goahttp.ErrInvalidType("test", "update", "*test.TestPayload", v)
		}
		id = p.ID // <<< Here is where the error happens
	}
```

The Error:
```
cannot use p.ID (variable of type *string) as string value in assignmentcannot use p.ID (variable of type *string) as string value in assignment
```

The thing is. the `delete` and `show` methods i added, that are nearly identical, outside of using DELETE and GET as their HTTP methods, work fine. `update` uses PUT

I have created an example repo where I reproduce the error here: https://github.com/Daegalus/goa-bug-example

If you run `goa gen test/design` and go into `gen/test/client/encode_decode.go` you will see the error.

I assume it is something to do with the `PUT` function. the `show` function is identical minus the `GET` function.

This happens in v3.9.1 and v3.10.0


Pull request description:
Fix required path params request init
If the method payload is an object then the code generation algorithm should look at whether the corresponding attribute is required instead of relying on the params attribute as it may make the field required there.

Fix #3166 

Patch:
diff --git a/http/codegen/service_data.go b/http/codegen/service_data.go
index 24fe8d37..5b3710c4 100644
--- a/http/codegen/service_data.go
+++ b/http/codegen/service_data.go
@@ -656,6 +656,10 @@ func (d ServicesData) analyze(hs *expr.HTTPServiceExpr) *ServiceData {
 						patt := pathParamsObj.Attribute(arg)
 						att := makeHTTPType(patt)
 						pointer := a.Params.IsPrimitivePointer(arg, true)
+						if expr.IsObject(a.MethodExpr.Payload.Type) {
+							// Path params may override requiredness, need to check payload.
+							pointer = a.MethodExpr.Payload.IsPrimitivePointer(arg, true)
+						}
 						name := rd.Scope.Name(codegen.Goify(arg, false))
 						var vcode string
 						if att.Validation != nil {


Test patch:
diff --git a/http/codegen/client_encode_test.go b/http/codegen/client_encode_test.go
index 4231b5bc..40864689 100644
--- a/http/codegen/client_encode_test.go
+++ b/http/codegen/client_encode_test.go
@@ -209,6 +209,7 @@ func TestClientBuildRequest(t *testing.T) {
 		{"path-string", testdata.PayloadPathStringDSL, testdata.PathStringRequestBuildCode},
 		{"path-string-required", testdata.PayloadPathStringValidateDSL, testdata.PathStringRequiredRequestBuildCode},
 		{"path-string-default", testdata.PayloadPathStringDefaultDSL, testdata.PathStringDefaultRequestBuildCode},
+		{"path-object", testdata.PayloadPathObjectDSL, testdata.PathObjectRequestBuildCode},
 	}
 	for _, c := range cases {
 		t.Run(c.Name, func(t *testing.T) {
diff --git a/http/codegen/testdata/client_request_build_functions.go b/http/codegen/testdata/client_request_build_functions.go
index e3477114..55c98e38 100644
--- a/http/codegen/testdata/client_request_build_functions.go
+++ b/http/codegen/testdata/client_request_build_functions.go
@@ -82,3 +82,32 @@ func (c *Client) BuildMethodPathStringDefaultRequest(ctx context.Context, v inte
 	return req, nil
 }
 `
+
+const PathObjectRequestBuildCode = `// BuildMethodPathObjectRequest instantiates a HTTP request object with method
+// and path set to call the "ServicePathObject" service "MethodPathObject"
+// endpoint
+func (c *Client) BuildMethodPathObjectRequest(ctx context.Context, v interface{}) (*http.Request, error) {
+	var (
+		id string
+	)
+	{
+		p, ok := v.(*servicepathobject.MethodPathObjectPayload)
+		if !ok {
+			return nil, goahttp.ErrInvalidType("ServicePathObject", "MethodPathObject", "*servicepathobject.MethodPathObjectPayload", v)
+		}
+		if p.ID != nil {
+			id = *p.ID
+		}
+	}
+	u := &url.URL{Scheme: c.scheme, Host: c.host, Path: MethodPathObjectServicePathObjectPath(id)}
+	req, err := http.NewRequest("PUT", u.String(), nil)
+	if err != nil {
+		return nil, goahttp.ErrInvalidURL("ServicePathObject", "MethodPathObject", u.String(), err)
+	}
+	if ctx != nil {
+		req = req.WithContext(ctx)
+	}
+
+	return req, nil
+}
+`
diff --git a/http/codegen/testdata/payload_dsls.go b/http/codegen/testdata/payload_dsls.go
index 38c9ce70..678f2572 100644
--- a/http/codegen/testdata/payload_dsls.go
+++ b/http/codegen/testdata/payload_dsls.go
@@ -1454,6 +1454,23 @@ var PayloadPathStringDefaultDSL = func() {
 	})
 }
 
+var PayloadPathObjectDSL = func() {
+	Service("ServicePathObject", func() {
+		Method("MethodPathObject", func() {
+			Payload(func() {
+				Attribute("id")
+			})
+			HTTP(func() {
+				PUT("/{id}")
+				Params(func() {
+					Param("id")
+					Required("id")
+				})
+			})
+		})
+	})
+}
+
 var PayloadPathArrayStringDSL = func() {
 	Service("ServicePathArrayString", func() {
 		Method("MethodPathArrayString", func() {