Repository: goadesign/goa
Pull request #2853 (2021-05-21 02:06:01)

Always encode all result attributes
This PR changes the HTTP encoding of responses to guarantee that all the result type attributes are transmitted. It does that by writing any attribute not already written to the response body, headers or cookies to special headers prefixed with `Goa-`. This is especially convenient for transmitting error details back to requests using HTTP verbs that do not permit writing a response body (HEAD).

For example:

```go
var Result = Type("Result", func() {
    Attribute("foo")
    Attribute("bar")
})

var _ = Service("service", func() {
    Method("head", func() {
        Result(Result)
    })
    HTTP(func() {
        HEAD("/")
        Response(StatusOK, func() {
            Body(Empty) // Body is empty, attributes "foo" and "bar" will be transmitted via HTTP headers,
        })
    })
})
```

Note that it is possible to avoid having all the result type attributes being transmitted by using views (e.g. defining a default view explicitly that omits certain attributes.). This is especially useful when using `Tag` to define multiple possible response status code (the tagged attribute used to select the status code can be omitted from the response).

raphael: This is great, thank you!

Patch:
diff --git a/dsl/http.go b/dsl/http.go
index 23cae95c..7d23defa 100644
--- a/dsl/http.go
+++ b/dsl/http.go
@@ -535,7 +535,7 @@ func CookiePath(p string) {
 	cookieAttribute("path", p)
 }
 
-// CookieSecure initializes the "secute" attribute of a HTTP response cookie
+// CookieSecure initializes the "secure" attribute of a HTTP response cookie
 // with "Secure".
 //
 // CookieSecure must appear in a Cookie expression.
diff --git a/expr/http_endpoint.go b/expr/http_endpoint.go
index 65da13eb..4fa04bc1 100644
--- a/expr/http_endpoint.go
+++ b/expr/http_endpoint.go
@@ -695,6 +695,7 @@ func (e *HTTPEndpointExpr) Finalize() {
 		r.Finalize(e, e.MethodExpr.Result)
 		r.Body = httpResponseBody(e, r)
 		r.Body.Finalize()
+		r.mapUnmappedAttrs(e.MethodExpr.Result)
 	}
 
 	// Make sure all error types are user types and have a body.
diff --git a/expr/http_error.go b/expr/http_error.go
index 893e976e..9f9d8243 100644
--- a/expr/http_error.go
+++ b/expr/http_error.go
@@ -41,6 +41,46 @@ func (e *HTTPErrorExpr) Validate() *eval.ValidationErrors {
 			verr.Add(e, "Error %#v does not match an error defined in the API", e.Name)
 		}
 	}
+
+	var ee *ErrorExpr
+	switch p := e.Response.Parent.(type) {
+	case *HTTPEndpointExpr:
+		ee = p.MethodExpr.Error(e.Name)
+	case *HTTPServiceExpr:
+		ee = p.Error(e.Name)
+	case *RootExpr:
+		ee = Root.Error(e.Name)
+	}
+
+	// validate headers
+	if e.Response.Headers != nil && !e.Response.Headers.IsEmpty() {
+		verr.Merge(e.Response.Headers.Validate("HTTP error response headers", e.Response))
+		switch {
+		case ee.Type == Empty:
+			verr.Add(e.Response, "response defines headers but error type is empty")
+		case IsObject(ee.Type):
+			for _, h := range *AsObject(e.Response.Headers.Type) {
+				att := ee.Find(h.Name)
+				if att == nil {
+					verr.Add(e.Response, "header %q has no equivalent attribute in error type, use notation 'attribute_name:header_name' to identify corresponding error type attribute.", h.Name)
+				} else if IsArray(att.Type) {
+					if !IsPrimitive(AsArray(att.Type).ElemType.Type) {
+						verr.Add(e.Response, "attribute %q used in HTTP headers must be a primitive type or an array of primitive types.", h.Name)
+					}
+				} else if !IsPrimitive(att.Type) {
+					verr.Add(e.Response, "attribute %q used in HTTP headers must be a primitive type or an array of primitive types.", h.Name)
+				}
+			}
+		case len(*AsObject(e.Response.Headers.Type)) > 1:
+			verr.Add(e.Response, "response defines more than one headers but error type is not an object")
+		case IsArray(ee.Type):
+			if !IsPrimitive(AsArray(ee.Type).ElemType.Type) {
+				verr.Add(e.Response, "Array error type is mapped to an HTTP header but is not an array of primitive types.")
+			}
+		case IsMap(ee.Type):
+			verr.Add(e.Response, "error type must be a primitive type or an array of primitive types.")
+		}
+	}
 	return verr
 }
 
@@ -60,6 +100,7 @@ func (e *HTTPErrorExpr) Finalize(a *HTTPEndpointExpr) {
 	if e.Response.Body == nil {
 		e.Response.Body = httpErrorResponseBody(a, e)
 	}
+	e.Response.mapUnmappedAttrs(e.AttributeExpr)
 
 	// Initialize response content type if result is media type.
 	if e.Response.Body.Type == Empty {
diff --git a/expr/http_response.go b/expr/http_response.go
index e8c7bd6b..fc01a596 100644
--- a/expr/http_response.go
+++ b/expr/http_response.go
@@ -188,8 +188,7 @@ func (r *HTTPResponseExpr) Validate(e *HTTPEndpointExpr) *eval.ValidationErrors
 				t := resultAttributeType(h.Name)
 				if t == nil {
 					verr.Add(r, "header %q has no equivalent attribute in%s result type, use notation 'attribute_name:header_name' to identify corresponding result type attribute.", h.Name, inview)
-				}
-				if IsArray(t) {
+				} else if IsArray(t) {
 					if !IsPrimitive(AsArray(t).ElemType.Type) {
 						verr.Add(e, "attribute %q used in HTTP headers must be a primitive type or an array of primitive types.", h.Name)
 					}
@@ -256,53 +255,57 @@ func (r *HTTPResponseExpr) Validate(e *HTTPEndpointExpr) *eval.ValidationErrors
 func (r *HTTPResponseExpr) Finalize(a *HTTPEndpointExpr, svcAtt *AttributeExpr) {
 	r.Parent = a
 
-	if r.Body != nil && r.Body.Type != Empty {
-		bodyAtt := svcAtt
-		if o, ok := r.Body.Meta["origin:attribute"]; ok {
-			bodyAtt = svcAtt.Find(o[0])
-		}
-		bodyObj := AsObject(bodyAtt.Type)
-		if body := AsObject(r.Body.Type); body != nil {
-			for _, nat := range *body {
-				n := nat.Name
-				n = strings.Split(n, ":")[0]
-				var att, patt *AttributeExpr
-				var required bool
-				if bodyObj != nil {
-					att = bodyObj.Attribute(n)
-					required = bodyAtt.IsRequired(n)
-				} else {
-					att = bodyAtt
-					required = bodyAtt.Type != Empty
-				}
-				initAttrFromDesign(att, patt)
-				if required {
-					if r.Body.Validation == nil {
-						r.Body.Validation = &ValidationExpr{}
+	if r.Body != nil {
+		if r.Body.Type != Empty {
+			bodyAtt := svcAtt
+			if o, ok := r.Body.Meta["origin:attribute"]; ok {
+				bodyAtt = svcAtt.Find(o[0])
+			}
+			bodyObj := AsObject(bodyAtt.Type)
+			if body := AsObject(r.Body.Type); body != nil {
+				for _, nat := range *body {
+					n := nat.Name
+					n = strings.Split(n, ":")[0]
+					var att, patt *AttributeExpr
+					var required bool
+					if bodyObj != nil {
+						att = bodyObj.Attribute(n)
+						required = bodyAtt.IsRequired(n)
+					} else {
+						att = bodyAtt
+						required = bodyAtt.Type != Empty
+					}
+					initAttrFromDesign(att, patt)
+					if required {
+						if r.Body.Validation == nil {
+							r.Body.Validation = &ValidationExpr{}
+						}
+						r.Body.Validation.AddRequired(n)
 					}
-					r.Body.Validation.AddRequired(n)
+				}
+				// Remember original name for example to generate friendlier OpenAPI specs.
+				if t, ok := r.Body.Type.(UserType); ok {
+					t.Attribute().AddMeta("name:original", t.Name())
+				}
+				// Wrap object with user type to simplify response rendering code.
+				r.Body.Type = &UserTypeExpr{
+					AttributeExpr: DupAtt(r.Body),
+					TypeName:      fmt.Sprintf("%s%sResponseBody", a.Service.Name(), a.Name()),
 				}
 			}
-			// Remember original name for example to generate friendlier OpenAPI specs.
-			if t, ok := r.Body.Type.(UserType); ok {
-				t.Attribute().AddMeta("name:original", t.Name())
-			}
-			// Wrap object with user type to simplify response rendering code.
-			r.Body.Type = &UserTypeExpr{
-				AttributeExpr: DupAtt(r.Body),
-				TypeName:      fmt.Sprintf("%s%sResponseBody", a.Service.Name(), a.Name()),
+			if r.Body.Meta == nil {
+				r.Body.Meta = bodyAtt.Meta
 			}
 		}
-		if r.Body.Meta == nil {
-			r.Body.Meta = bodyAtt.Meta
-		}
 	}
+
 	// Set response content type if empty and if set in the result type
 	if r.ContentType == "" {
 		if rt, ok := svcAtt.Type.(*ResultTypeExpr); ok && rt.ContentType != "" {
 			r.ContentType = rt.ContentType
 		}
 	}
+
 	initAttr(r.Headers, svcAtt)
 	initAttr(r.Cookies, svcAtt)
 }
@@ -328,6 +331,63 @@ func (r *HTTPResponseExpr) Dup() *HTTPResponseExpr {
 	return &res
 }
 
+// mapUnmappedAttrs maps any unmapped attributes to the response headers.
+// Unmapped attributes refer to the attributes in the given service type
+// (Result or Error) that are not mapped to response body, headers, cookies, or
+// tags. Such unmapped attributes are mapped to special goa headers in the form
+// of "Goa-Attribute(-<Attribute Name>)".
+func (r *HTTPResponseExpr) mapUnmappedAttrs(svcAtt *AttributeExpr) {
+	if svcAtt.Type == Empty {
+		return
+	}
+
+	// map attributes to headers that are not explicitly mapped
+	switch {
+	case IsObject(svcAtt.Type):
+		// map the attribute names in the service type to response headers if
+		// not mapped explicitly.
+
+		var originAttr string
+		{
+			if r.Body != nil {
+				if o, ok := r.Body.Meta["origin:attribute"]; ok {
+					originAttr = o[0]
+				}
+			}
+		}
+		// if response body was mapped explicitly using Body(<attribute name>) then
+		// we must make sure we map all the other unmapped attributes to headers.
+		if r.Body == nil || r.Body.Type == Empty || originAttr != "" {
+			for _, nat := range *(AsObject(svcAtt.Type)) {
+				if originAttr == nat.Name {
+					continue
+				}
+				if _, ok := r.Headers.FindKey(nat.Name); ok {
+					continue
+				}
+				if _, ok := r.Cookies.FindKey(nat.Name); ok {
+					continue
+				}
+				if r.Tag[0] == nat.Name {
+					continue
+				}
+				r.Headers.Type.(*Object).Set(nat.Name, nat.Attribute)
+				r.Headers.Map("goa-attribute-"+nat.Name, nat.Name)
+				if svcAtt.IsRequired(nat.Name) {
+					if r.Headers.Validation == nil {
+						r.Headers.Validation = &ValidationExpr{}
+					}
+					r.Headers.Validation.AddRequired(nat.Name)
+				}
+			}
+		}
+	default:
+		if r.Headers.IsEmpty() && r.Cookies.IsEmpty() && (r.Body == nil || r.Body.Type == Empty) {
+			r.Headers.Type.(*Object).Set("goa-attribute", svcAtt)
+		}
+	}
+}
+
 // bodyAllowedForStatus reports whether a given response status code
 // permits a body. See RFC 2616, section 4.4.
 // See https://golang.org/src/net/http/transfer.go
diff --git a/http/codegen/server.go b/http/codegen/server.go
index c5d2a65d..0eef29d1 100644
--- a/http/codegen/server.go
+++ b/http/codegen/server.go
@@ -1248,12 +1248,15 @@ const responseT = `{{ define "response" -}}
 		{{- $initDef := and (or .FieldPointer .Slice) .DefaultValue (not $.TagName) }}
 		{{- $checkNil := and (or .FieldPointer .Slice (eq .Type.Name "bytes") (eq .Type.Name "any") $initDef) (not $.TagName) }}
 		{{- if $checkNil }}
-	if res.{{ if $.ViewedResult }}Projected.{{ end }}{{ .FieldName }} != nil {
+	if res{{ if .FieldName }}.{{ end }}{{ if $.ViewedResult }}Projected.{{ end }}{{ if .FieldName }}{{ .FieldName }}{{ end }} != nil {
 		{{- end }}
 
 		{{- if and (eq .Type.Name "string") (not (isAliased .FieldType)) }}
 	w.Header().Set("{{ .CanonicalName }}", {{ if or .FieldPointer $.ViewedResult }}*{{ end }}res{{ if $.ViewedResult }}.Projected{{ end }}{{ if .FieldName }}.{{ .FieldName }}{{ end }})
 		{{- else }}
+{{- if not $checkNil }}
+{
+{{- end }}
 			{{- if isAliased .FieldType }}
 	val := {{ goTypeRef .Type }}({{ if .FieldPointer }}*{{ end }}res{{ if $.ViewedResult }}.Projected{{ end }}{{ if .FieldName }}.{{ .FieldName }}{{ end }})
 	{{ template "header_conversion" (headerConversionData .Type (printf "%ss" .VarName) true "val") }}
@@ -1262,6 +1265,9 @@ const responseT = `{{ define "response" -}}
 	{{ template "header_conversion" (headerConversionData .Type (printf "%ss" .VarName) (not .FieldPointer) "val") }}
 			{{- end }}
 	w.Header().Set("{{ .CanonicalName }}", {{ .VarName }}s)
+{{- if not $checkNil }}
+}
+{{- end }}
 		{{- end }}
 
 		{{- if $initDef }}


Test patch:
diff --git a/expr/http_error_test.go b/expr/http_error_test.go
new file mode 100644
index 00000000..50a92f3c
--- /dev/null
+++ b/expr/http_error_test.go
@@ -0,0 +1,163 @@
+package expr_test
+
+import (
+	"testing"
+
+	. "goa.design/goa/v3/dsl"
+	"goa.design/goa/v3/expr"
+)
+
+func TestHTTPErrorResponseValidation(t *testing.T) {
+	cases := []struct {
+		Name  string
+		DSL   func()
+		Error string
+	}{
+		{"header string error", stringErrorResponseWithHeadersDSL, ""},
+		{"header object result", objectErrorResponseWithHeadersDSL, ""},
+		{"header array result", arrayErrorResponseWithHeadersDSL, ""},
+		{"header map result", mapErrorResponseWithHeadersDSL, `HTTP response of service "MapErrorResponseWithHeaders" HTTP endpoint "Method": attribute "foo" used in HTTP headers must be a primitive type or an array of primitive types.`},
+		{"implicit object in header", implicitObjectErrorResponseWithHeadersDSL, `HTTP response of service "ArrayObjectErrorResponseWithHeaders" HTTP endpoint "Method": attribute "foo" used in HTTP headers must be a primitive type or an array of primitive types.`},
+		{"array of object in header", arrayObjectErrorResponseWithHeadersDSL, `HTTP response of service "ArrayObjectErrorResponseWithHeaders" HTTP endpoint "Method": Array error type is mapped to an HTTP header but is not an array of primitive types.`},
+		{"map in header", mapErrorTypeResponseWithHeadersDSL, `HTTP response of service "MapErrorTypeResponseWithHeaders" HTTP endpoint "Method": error type must be a primitive type or an array of primitive types.`},
+		{"missing header result attribute", missingHeaderErrorAttributeDSL, `HTTP response of service "MissingHeaderErrorAttribute" HTTP endpoint "Method": header "bar" has no equivalent attribute in error type, use notation 'attribute_name:header_name' to identify corresponding error type attribute.`},
+	}
+	for _, c := range cases {
+		t.Run(c.Name, func(t *testing.T) {
+			if c.Error == "" {
+				expr.RunDSL(t, c.DSL)
+			} else {
+				err := expr.RunInvalidDSL(t, c.DSL)
+				if err.Error() != c.Error {
+					t.Errorf("\ngot error %q\nexpected %q", err.Error(), c.Error)
+				}
+			}
+		})
+	}
+}
+
+var stringErrorResponseWithHeadersDSL = func() {
+	Service("StringErrorResponseWithHeaders", func() {
+		Method("Method", func() {
+			Error("error", String)
+			HTTP(func() {
+				POST("/")
+				Response("error", func() {
+					Header("Location")
+				})
+			})
+		})
+	})
+}
+
+var objectErrorResponseWithHeadersDSL = func() {
+	Service("ObjectErrorResponseWithHeaders", func() {
+		Method("Method", func() {
+			Error("error", func() {
+				Attribute("foo", String)
+			})
+			HTTP(func() {
+				POST("/")
+				Response("error", func() {
+					Header("foo:Location")
+				})
+			})
+		})
+	})
+}
+
+var implicitObjectErrorResponseWithHeadersDSL = func() {
+	Service("ArrayObjectErrorResponseWithHeaders", func() {
+		Method("Method", func() {
+			Error("error", func() {
+				Attribute("foo", func() {
+					Attribute("bar", String)
+					Attribute("baz", String)
+				})
+			})
+			HTTP(func() {
+				POST("/")
+				Response("error", func() {
+					Header("foo:Location")
+				})
+			})
+		})
+	})
+}
+
+var arrayObjectErrorResponseWithHeadersDSL = func() {
+	var Obj = Type("Obj", func() {
+		Attribute("foo", String)
+	})
+	Service("ArrayObjectErrorResponseWithHeaders", func() {
+		Method("Method", func() {
+			Error("error", ArrayOf(Obj))
+			HTTP(func() {
+				POST("/")
+				Response("error", func() {
+					Header("foo:Location")
+				})
+			})
+		})
+	})
+}
+
+var mapErrorTypeResponseWithHeadersDSL = func() {
+	Service("MapErrorTypeResponseWithHeaders", func() {
+		Method("Method", func() {
+			Error("error", MapOf(String, Int))
+			HTTP(func() {
+				POST("/")
+				Response("error", func() {
+					Header("Location")
+				})
+			})
+		})
+	})
+}
+
+var arrayErrorResponseWithHeadersDSL = func() {
+	Service("ArrayErrorResponseWithHeaders", func() {
+		Method("Method", func() {
+			Error("error", func() {
+				Attribute("foo", ArrayOf(String))
+			})
+			HTTP(func() {
+				POST("/")
+				Response("error", func() {
+					Header("foo:Location")
+				})
+			})
+		})
+	})
+}
+
+var mapErrorResponseWithHeadersDSL = func() {
+	Service("MapErrorResponseWithHeaders", func() {
+		Method("Method", func() {
+			Error("error", func() {
+				Attribute("foo", MapOf(String, String))
+			})
+			HTTP(func() {
+				POST("/")
+				Response("error", func() {
+					Header("foo:Location")
+				})
+			})
+		})
+	})
+}
+
+var missingHeaderErrorAttributeDSL = func() {
+	Service("MissingHeaderErrorAttribute", func() {
+		Method("Method", func() {
+			Error("error")
+			HTTP(func() {
+				POST("/")
+				Response("error", func() {
+					Header("bar")
+				})
+			})
+		})
+	})
+}
diff --git a/expr/http_response_test.go b/expr/http_response_test.go
index 0e701546..4a6b2e67 100644
--- a/expr/http_response_test.go
+++ b/expr/http_response_test.go
@@ -29,8 +29,7 @@ func TestHTTPResponseValidation(t *testing.T) {
 		{"implicit object in header", implicitObjectResultResponseWithHeadersDSL, `service "ArrayObjectResultResponseWithHeaders" HTTP endpoint "Method": attribute "foo" used in HTTP headers must be a primitive type or an array of primitive types.`},
 		{"array of object in header", arrayObjectResultResponseWithHeadersDSL, `service "ArrayObjectResultResponseWithHeaders" HTTP endpoint "Method": Array result is mapped to an HTTP header but is not an array of primitive types.`},
 		{"not string or []byte", intResultResponseWithTextContentTypeDSL, `HTTP response of service "StringResultResponseWithHeaders" HTTP endpoint "Method": Result type must be String or Bytes when ContentType is 'text/plain'`},
-		{"missing header result attribute", missingHeaderResultAttributeDSL, `HTTP response of service "MissingHeaderResultAttribute" HTTP endpoint "Method": header "bar" has no equivalent attribute in result type, use notation 'attribute_name:header_name' to identify corresponding result type attribute.
-service "MissingHeaderResultAttribute" HTTP endpoint "Method": attribute "bar" used in HTTP headers must be a primitive type or an array of primitive types.`},
+		{"missing header result attribute", missingHeaderResultAttributeDSL, `HTTP response of service "MissingHeaderResultAttribute" HTTP endpoint "Method": header "bar" has no equivalent attribute in result type, use notation 'attribute_name:header_name' to identify corresponding result type attribute.`},
 		{"missing cookie result attribute", missingCookieResultAttributeDSL, `HTTP response of service "MissingCookieResultAttribute" HTTP endpoint "Method": cookie "bar" has no equivalent attribute in result type, use notation 'attribute_name:cookie_name' to identify corresponding result type attribute.
 service "MissingCookieResultAttribute" HTTP endpoint "Method": attribute "bar" used in HTTP cookies must be a primitive type.`},
 		{"skip encode and gRPC", skipEncodeAndGRPCDSL, `service "SkipEncodeAndGRPC" HTTP endpoint "Method": Endpoint response cannot use SkipResponseBodyEncodeDecode and define a gRPC transport.`},
diff --git a/http/codegen/client_body_types_test.go b/http/codegen/client_body_types_test.go
index b516e3fb..f0618e63 100644
--- a/http/codegen/client_body_types_test.go
+++ b/http/codegen/client_body_types_test.go
@@ -222,12 +222,13 @@ const ExplicitBodyPrimitiveResultMultipleViewsInitCode = `// NewMethodExplicitBo
 // builds a "ServiceExplicitBodyPrimitiveResultMultipleView" service
 // "MethodExplicitBodyPrimitiveResultMultipleView" endpoint result from a HTTP
 // "OK" response.
-func NewMethodExplicitBodyPrimitiveResultMultipleViewResulttypemultipleviewsOK(body string, c *string) *serviceexplicitbodyprimitiveresultmultipleviewviews.ResulttypemultipleviewsView {
+func NewMethodExplicitBodyPrimitiveResultMultipleViewResulttypemultipleviewsOK(body string, c *string, b *string) *serviceexplicitbodyprimitiveresultmultipleviewviews.ResulttypemultipleviewsView {
 	v := body
 	res := &serviceexplicitbodyprimitiveresultmultipleviewviews.ResulttypemultipleviewsView{
 		A: &v,
 	}
 	res.C = c
+	res.B = b
 
 	return res
 }
@@ -237,7 +238,7 @@ const ExplicitBodyUserResultMultipleViewsInitCode = `// NewMethodExplicitBodyUse
 // a "ServiceExplicitBodyUserResultMultipleView" service
 // "MethodExplicitBodyUserResultMultipleView" endpoint result from a HTTP "OK"
 // response.
-func NewMethodExplicitBodyUserResultMultipleViewResulttypemultipleviewsOK(body *MethodExplicitBodyUserResultMultipleViewResponseBody, c *string) *serviceexplicitbodyuserresultmultipleviewviews.ResulttypemultipleviewsView {
+func NewMethodExplicitBodyUserResultMultipleViewResulttypemultipleviewsOK(body *MethodExplicitBodyUserResultMultipleViewResponseBody, c *string, b *string) *serviceexplicitbodyuserresultmultipleviewviews.ResulttypemultipleviewsView {
 	v := &serviceexplicitbodyuserresultmultipleviewviews.UserTypeView{
 		X: body.X,
 		Y: body.Y,
@@ -246,6 +247,7 @@ func NewMethodExplicitBodyUserResultMultipleViewResulttypemultipleviewsOK(body *
 		A: v,
 	}
 	res.C = c
+	res.B = b
 
 	return res
 }
@@ -710,14 +712,14 @@ func ValidateRtResponseBody(body *RtResponseBody) (err error) {
 const EmptyErrorResponseBodyClientTypesFile = `// NewMethodEmptyErrorResponseBodyInternalError builds a
 // ServiceEmptyErrorResponseBody service MethodEmptyErrorResponseBody endpoint
 // internal_error error.
-func NewMethodEmptyErrorResponseBodyInternalError(name string, id string, message string, fault bool, temporary bool, timeout bool) *goa.ServiceError {
+func NewMethodEmptyErrorResponseBodyInternalError(name string, id string, message string, temporary bool, timeout bool, fault bool) *goa.ServiceError {
 	v := &goa.ServiceError{}
 	v.Name = name
 	v.ID = id
 	v.Message = message
-	v.Fault = fault
 	v.Temporary = temporary
 	v.Timeout = timeout
+	v.Fault = fault
 
 	return v
 }
diff --git a/http/codegen/client_decode_test.go b/http/codegen/client_decode_test.go
index af565db0..38710887 100644
--- a/http/codegen/client_decode_test.go
+++ b/http/codegen/client_decode_test.go
@@ -31,6 +31,14 @@ func TestClientDecode(t *testing.T) {
 		{"with-headers-dsl-viewed-result", testdata.WithHeadersBlockViewedResultDSL, testdata.WithHeadersBlockViewedResultResponseDecodeCode},
 		{"validate-error-response-type", testdata.ValidateErrorResponseTypeDSL, testdata.ValidateErrorResponseTypeDecodeCode},
 		{"empty-error-response-body", testdata.EmptyErrorResponseBodyDSL, testdata.EmptyErrorResponseBodyDecodeCode},
+
+		{"unmapped-result-object", testdata.UnmappedResultObjectDSL, testdata.UnmappedResultObjectDecodeCode},
+		{"unmapped-result-object-validate", testdata.UnmappedResultObjectValidateDSL, testdata.UnmappedResultObjectValidateDecodeCode},
+		{"unmapped-result-object-with-headers", testdata.UnmappedResultObjectWithHeadersDSL, testdata.UnmappedResultObjectWithHeadersDecodeCode},
+		{"unmapped-result-primitive", testdata.UnmappedResultPrimitiveDSL, testdata.UnmappedResultPrimitiveDecodeCode},
+		{"unmapped-result-primitive-validate", testdata.UnmappedResultPrimitiveValidateDSL, testdata.UnmappedResultPrimitiveValidateDecodeCode},
+		{"unmapped-result-array", testdata.UnmappedResultArrayDSL, testdata.UnmappedResultArrayDecodeCode},
+		{"unmapped-result-array-validate", testdata.UnmappedResultArrayValidateDSL, testdata.UnmappedResultArrayValidateDecodeCode},
 	}
 	for _, c := range cases {
 		t.Run(c.Name, func(t *testing.T) {
diff --git a/http/codegen/server_encode_test.go b/http/codegen/server_encode_test.go
index 18457b76..52412410 100644
--- a/http/codegen/server_encode_test.go
+++ b/http/codegen/server_encode_test.go
@@ -80,6 +80,15 @@ func TestEncode(t *testing.T) {
 
 		{"empty-server-response", testdata.EmptyServerResponseDSL, testdata.EmptyServerResponseEncodeCode},
 		{"empty-server-response-with-tags", testdata.EmptyServerResponseWithTagsDSL, testdata.EmptyServerResponseWithTagsEncodeCode},
+
+		{"unmapped-result-object", testdata.UnmappedResultObjectDSL, testdata.UnmappedResultObjectEncodeCode},
+		{"unmapped-result-object-with-body", testdata.UnmappedResultObjectWithBodyDSL, testdata.UnmappedResultObjectWithBodyEncodeCode},
+		{"unmapped-result-object-validate", testdata.UnmappedResultObjectValidateDSL, testdata.UnmappedResultObjectValidateEncodeCode},
+		{"unmapped-result-object-with-headers", testdata.UnmappedResultObjectWithHeadersDSL, testdata.UnmappedResultObjectWithHeadersEncodeCode},
+		{"unmapped-result-primitive", testdata.UnmappedResultPrimitiveDSL, testdata.UnmappedResultPrimitiveEncodeCode},
+		{"unmapped-result-primitive-validate", testdata.UnmappedResultPrimitiveValidateDSL, testdata.UnmappedResultPrimitiveValidateEncodeCode},
+		{"unmapped-result-array", testdata.UnmappedResultArrayDSL, testdata.UnmappedResultArrayEncodeCode},
+		{"unmapped-result-array-validate", testdata.UnmappedResultArrayValidateDSL, testdata.UnmappedResultArrayValidateEncodeCode},
 	}
 	for _, c := range cases {
 		t.Run(c.Name, func(t *testing.T) {
diff --git a/http/codegen/testdata/error_encoder_code.go b/http/codegen/testdata/error_encoder_code.go
index 1fcde8a6..0448b370 100644
--- a/http/codegen/testdata/error_encoder_code.go
+++ b/http/codegen/testdata/error_encoder_code.go
@@ -55,17 +55,21 @@ func EncodeMethodPrimitiveErrorInResponseHeaderError(encoder func(context.Contex
 		switch en.ErrorName() {
 		case "bad_request":
 			res := v.(serviceprimitiveerrorinresponseheader.BadRequest)
-			val := string(res)
-			string_s := val
-			w.Header().Set("String", string_s)
+			{
+				val := string(res)
+				string_s := val
+				w.Header().Set("String", string_s)
+			}
 			w.Header().Set("goa-error", res.ErrorName())
 			w.WriteHeader(http.StatusBadRequest)
 			return nil
 		case "internal_error":
 			res := v.(serviceprimitiveerrorinresponseheader.InternalError)
-			val := int(res)
-			int_s := strconv.Itoa(val)
-			w.Header().Set("Int", int_s)
+			{
+				val := int(res)
+				int_s := strconv.Itoa(val)
+				w.Header().Set("Int", int_s)
+			}
 			w.Header().Set("goa-error", res.ErrorName())
 			w.WriteHeader(http.StatusInternalServerError)
 			return nil
@@ -283,25 +287,33 @@ func EncodeMethodEmptyErrorResponseBodyError(encoder func(context.Context, http.
 		case "internal_error":
 			res := v.(*goa.ServiceError)
 			w.Header().Set("Error-Name", res.Name)
-			w.Header().Set("Error-Id", res.ID)
-			w.Header().Set("Error-Message", res.Message)
-			val := res.Fault
-			faults := strconv.FormatBool(val)
-			w.Header().Set("Error-Fault", faults)
-			val := res.Temporary
-			temporarys := strconv.FormatBool(val)
-			w.Header().Set("Error-Temporary", temporarys)
-			val := res.Timeout
-			timeouts := strconv.FormatBool(val)
-			w.Header().Set("Error-Timeout", timeouts)
+			w.Header().Set("Goa-Attribute-Id", res.ID)
+			w.Header().Set("Goa-Attribute-Message", res.Message)
+			{
+				val := res.Temporary
+				temporarys := strconv.FormatBool(val)
+				w.Header().Set("Goa-Attribute-Temporary", temporarys)
+			}
+			{
+				val := res.Timeout
+				timeouts := strconv.FormatBool(val)
+				w.Header().Set("Goa-Attribute-Timeout", timeouts)
+			}
+			{
+				val := res.Fault
+				faults := strconv.FormatBool(val)
+				w.Header().Set("Goa-Attribute-Fault", faults)
+			}
 			w.Header().Set("goa-error", res.ErrorName())
 			w.WriteHeader(http.StatusInternalServerError)
 			return nil
 		case "not_found":
 			res := v.(serviceemptyerrorresponsebody.NotFound)
-			val := string(res)
-			inHeaders := val
-			w.Header().Set("In-Header", inHeaders)
+			{
+				val := string(res)
+				inHeaders := val
+				w.Header().Set("In-Header", inHeaders)
+			}
 			w.Header().Set("goa-error", res.ErrorName())
 			w.WriteHeader(http.StatusNotFound)
 			return nil
diff --git a/http/codegen/testdata/result_decode_functions.go b/http/codegen/testdata/result_decode_functions.go
index ae4034e8..8b635637 100644
--- a/http/codegen/testdata/result_decode_functions.go
+++ b/http/codegen/testdata/result_decode_functions.go
@@ -20,7 +20,19 @@ func DecodeMethodEmptyServerResponseResponse(decoder func(*http.Response) goahtt
 		}
 		switch resp.StatusCode {
 		case http.StatusOK:
-			res := NewMethodEmptyServerResponseResultOK()
+			var (
+				h   string
+				err error
+			)
+			hRaw := resp.Header.Get("Goa-Attribute-H")
+			if hRaw == "" {
+				err = goa.MergeErrors(err, goa.MissingFieldError("goa-attribute-h", "header"))
+			}
+			h = hRaw
+			if err != nil {
+				return nil, goahttp.ErrValidationError("ServiceEmptyServerResponse", "MethodEmptyServerResponse", err)
+			}
+			res := NewMethodEmptyServerResponseResultOK(h)
 			return res, nil
 		default:
 			body, _ := ioutil.ReadAll(resp.Body)
@@ -103,12 +115,22 @@ func DecodeMethodEmptyBodyResultMultipleViewResponse(decoder func(*http.Response
 		case http.StatusOK:
 			var (
 				c *string
+				a *string
+				b *string
 			)
 			cRaw := resp.Header.Get("Location")
 			if cRaw != "" {
 				c = &cRaw
 			}
-			p := NewMethodEmptyBodyResultMultipleViewResulttypemultipleviewsOK(c)
+			aRaw := resp.Header.Get("Goa-Attribute-A")
+			if aRaw != "" {
+				a = &aRaw
+			}
+			bRaw := resp.Header.Get("Goa-Attribute-B")
+			if bRaw != "" {
+				b = &bRaw
+			}
+			p := NewMethodEmptyBodyResultMultipleViewResulttypemultipleviewsOK(c, a, b)
 			view := resp.Header.Get("goa-view")
 			vres := &serviceemptybodyresultmultipleviewviews.Resulttypemultipleviews{Projected: p, View: view}
 			res := serviceemptybodyresultmultipleview.NewResulttypemultipleviews(vres)
@@ -158,12 +180,17 @@ func DecodeMethodExplicitBodyPrimitiveResultMultipleViewResponse(decoder func(*h
 			}
 			var (
 				c *string
+				b *string
 			)
 			cRaw := resp.Header.Get("Location")
 			if cRaw != "" {
 				c = &cRaw
 			}
-			p := NewMethodExplicitBodyPrimitiveResultMultipleViewResulttypemultipleviewsOK(body, c)
+			bRaw := resp.Header.Get("Goa-Attribute-B")
+			if bRaw != "" {
+				b = &bRaw
+			}
+			p := NewMethodExplicitBodyPrimitiveResultMultipleViewResulttypemultipleviewsOK(body, c, b)
 			view := resp.Header.Get("goa-view")
 			vres := &serviceexplicitbodyprimitiveresultmultipleviewviews.Resulttypemultipleviews{Projected: p, View: view}
 			if err = serviceexplicitbodyprimitiveresultmultipleviewviews.ValidateResulttypemultipleviews(vres); err != nil {
@@ -209,12 +236,17 @@ func DecodeMethodExplicitBodyUserResultMultipleViewResponse(decoder func(*http.R
 			}
 			var (
 				c *string
+				b *string
 			)
 			cRaw := resp.Header.Get("Location")
 			if cRaw != "" {
 				c = &cRaw
 			}
-			p := NewMethodExplicitBodyUserResultMultipleViewResulttypemultipleviewsOK(&body, c)
+			bRaw := resp.Header.Get("Goa-Attribute-B")
+			if bRaw != "" {
+				b = &bRaw
+			}
+			p := NewMethodExplicitBodyUserResultMultipleViewResulttypemultipleviewsOK(&body, c, b)
 			view := resp.Header.Get("goa-view")
 			vres := &serviceexplicitbodyuserresultmultipleviewviews.Resulttypemultipleviews{Projected: p, View: view}
 			if err = serviceexplicitbodyuserresultmultipleviewviews.ValidateResulttypemultipleviews(vres); err != nil {
@@ -366,7 +398,19 @@ func DecodeMethodEmptyServerResponseWithTagsResponse(decoder func(*http.Response
 			res.H = "true"
 			return res, nil
 		case http.StatusNoContent:
-			res := NewMethodEmptyServerResponseWithTagsResultNoContent()
+			var (
+				h   string
+				err error
+			)
+			hRaw := resp.Header.Get("Goa-Attribute-H")
+			if hRaw == "" {
+				err = goa.MergeErrors(err, goa.MissingFieldError("goa-attribute-h", "header"))
+			}
+			h = hRaw
+			if err != nil {
+				return nil, goahttp.ErrValidationError("ServiceEmptyServerResponseWithTags", "MethodEmptyServerResponseWithTags", err)
+			}
+			res := NewMethodEmptyServerResponseWithTagsResultNoContent(h)
 			return res, nil
 		default:
 			body, _ := ioutil.ReadAll(resp.Body)
@@ -856,9 +900,9 @@ func DecodeMethodEmptyErrorResponseBodyResponse(decoder func(*http.Response) goa
 				name      string
 				id        string
 				message   string
-				fault     bool
 				temporary bool
 				timeout   bool
+				fault     bool
 				err       error
 			)
 			nameRaw := resp.Header.Get("Error-Name")
@@ -866,31 +910,20 @@ func DecodeMethodEmptyErrorResponseBodyResponse(decoder func(*http.Response) goa
 				err = goa.MergeErrors(err, goa.MissingFieldError("Error-Name", "header"))
 			}
 			name = nameRaw
-			idRaw := resp.Header.Get("Error-Id")
+			idRaw := resp.Header.Get("Goa-Attribute-Id")
 			if idRaw == "" {
-				err = goa.MergeErrors(err, goa.MissingFieldError("Error-ID", "header"))
+				err = goa.MergeErrors(err, goa.MissingFieldError("goa-attribute-id", "header"))
 			}
 			id = idRaw
-			messageRaw := resp.Header.Get("Error-Message")
+			messageRaw := resp.Header.Get("Goa-Attribute-Message")
 			if messageRaw == "" {
-				err = goa.MergeErrors(err, goa.MissingFieldError("Error-message", "header"))
+				err = goa.MergeErrors(err, goa.MissingFieldError("goa-attribute-message", "header"))
 			}
 			message = messageRaw
 			{
-				faultRaw := resp.Header.Get("Error-Fault")
-				if faultRaw == "" {
-					return nil, goahttp.ErrValidationError("ServiceEmptyErrorResponseBody", "MethodEmptyErrorResponseBody", goa.MissingFieldError("Error-Fault", "header"))
-				}
-				v, err2 := strconv.ParseBool(faultRaw)
-				if err2 != nil {
-					err = goa.MergeErrors(err, goa.InvalidFieldTypeError("fault", faultRaw, "boolean"))
-				}
-				fault = v
-			}
-			{
-				temporaryRaw := resp.Header.Get("Error-Temporary")
+				temporaryRaw := resp.Header.Get("Goa-Attribute-Temporary")
 				if temporaryRaw == "" {
-					return nil, goahttp.ErrValidationError("ServiceEmptyErrorResponseBody", "MethodEmptyErrorResponseBody", goa.MissingFieldError("Error-Temporary", "header"))
+					return nil, goahttp.ErrValidationError("ServiceEmptyErrorResponseBody", "MethodEmptyErrorResponseBody", goa.MissingFieldError("goa-attribute-temporary", "header"))
 				}
 				v, err2 := strconv.ParseBool(temporaryRaw)
 				if err2 != nil {
@@ -899,9 +932,9 @@ func DecodeMethodEmptyErrorResponseBodyResponse(decoder func(*http.Response) goa
 				temporary = v
 			}
 			{
-				timeoutRaw := resp.Header.Get("Error-Timeout")
+				timeoutRaw := resp.Header.Get("Goa-Attribute-Timeout")
 				if timeoutRaw == "" {
-					return nil, goahttp.ErrValidationError("ServiceEmptyErrorResponseBody", "MethodEmptyErrorResponseBody", goa.MissingFieldError("Error-Timeout", "header"))
+					return nil, goahttp.ErrValidationError("ServiceEmptyErrorResponseBody", "MethodEmptyErrorResponseBody", goa.MissingFieldError("goa-attribute-timeout", "header"))
 				}
 				v, err2 := strconv.ParseBool(timeoutRaw)
 				if err2 != nil {
@@ -909,10 +942,21 @@ func DecodeMethodEmptyErrorResponseBodyResponse(decoder func(*http.Response) goa
 				}
 				timeout = v
 			}
+			{
+				faultRaw := resp.Header.Get("Goa-Attribute-Fault")
+				if faultRaw == "" {
+					return nil, goahttp.ErrValidationError("ServiceEmptyErrorResponseBody", "MethodEmptyErrorResponseBody", goa.MissingFieldError("goa-attribute-fault", "header"))
+				}
+				v, err2 := strconv.ParseBool(faultRaw)
+				if err2 != nil {
+					err = goa.MergeErrors(err, goa.InvalidFieldTypeError("fault", faultRaw, "boolean"))
+				}
+				fault = v
+			}
 			if err != nil {
 				return nil, goahttp.ErrValidationError("ServiceEmptyErrorResponseBody", "MethodEmptyErrorResponseBody", err)
 			}
-			return nil, NewMethodEmptyErrorResponseBodyInternalError(name, id, message, fault, temporary, timeout)
+			return nil, NewMethodEmptyErrorResponseBodyInternalError(name, id, message, temporary, timeout, fault)
 		case http.StatusNotFound:
 			var (
 				inHeader string
@@ -934,3 +978,454 @@ func DecodeMethodEmptyErrorResponseBodyResponse(decoder func(*http.Response) goa
 	}
 }
 `
+
+var UnmappedResultObjectDecodeCode = `// DecodeMethodUnmappedResultObjectResponse returns a decoder for responses
+// returned by the ServiceUnmappedResultObject MethodUnmappedResultObject
+// endpoint. restoreBody controls whether the response body should be restored
+// after having been read.
+func DecodeMethodUnmappedResultObjectResponse(decoder func(*http.Response) goahttp.Decoder, restoreBody bool) func(*http.Response) (interface{}, error) {
+	return func(resp *http.Response) (interface{}, error) {
+		if restoreBody {
+			b, err := ioutil.ReadAll(resp.Body)
+			if err != nil {
+				return nil, err
+			}
+			resp.Body = ioutil.NopCloser(bytes.NewBuffer(b))
+			defer func() {
+				resp.Body = ioutil.NopCloser(bytes.NewBuffer(b))
+			}()
+		} else {
+			defer resp.Body.Close()
+		}
+		switch resp.StatusCode {
+		case http.StatusOK:
+			var (
+				hstr   *string
+				hint32 *int32
+				err    error
+			)
+			hstrRaw := resp.Header.Get("Goa-Attribute-Hstr")
+			if hstrRaw != "" {
+				hstr = &hstrRaw
+			}
+			{
+				hint32Raw := resp.Header.Get("Goa-Attribute-Hint32")
+				if hint32Raw != "" {
+					v, err2 := strconv.ParseInt(hint32Raw, 10, 32)
+					if err2 != nil {
+						err = goa.MergeErrors(err, goa.InvalidFieldTypeError("hint32", hint32Raw, "integer"))
+					}
+					pv := int32(v)
+					hint32 = &pv
+				}
+			}
+			if err != nil {
+				return nil, goahttp.ErrValidationError("ServiceUnmappedResultObject", "MethodUnmappedResultObject", err)
+			}
+			res := NewMethodUnmappedResultObjectResultOK(hstr, hint32)
+			return res, nil
+		default:
+			body, _ := ioutil.ReadAll(resp.Body)
+			return nil, goahttp.ErrInvalidResponse("ServiceUnmappedResultObject", "MethodUnmappedResultObject", resp.StatusCode, string(body))
+		}
+	}
+}
+`
+
+var UnmappedResultObjectValidateDecodeCode = `// DecodeMethodUnmappedResultObjectValidateResponse returns a decoder for
+// responses returned by the ServiceUnmappedResultObjectValidate
+// MethodUnmappedResultObjectValidate endpoint. restoreBody controls whether
+// the response body should be restored after having been read.
+func DecodeMethodUnmappedResultObjectValidateResponse(decoder func(*http.Response) goahttp.Decoder, restoreBody bool) func(*http.Response) (interface{}, error) {
+	return func(resp *http.Response) (interface{}, error) {
+		if restoreBody {
+			b, err := ioutil.ReadAll(resp.Body)
+			if err != nil {
+				return nil, err
+			}
+			resp.Body = ioutil.NopCloser(bytes.NewBuffer(b))
+			defer func() {
+				resp.Body = ioutil.NopCloser(bytes.NewBuffer(b))
+			}()
+		} else {
+			defer resp.Body.Close()
+		}
+		switch resp.StatusCode {
+		case http.StatusOK:
+			var (
+				hstr   *string
+				hint32 *int32
+				err    error
+			)
+			hstrRaw := resp.Header.Get("Goa-Attribute-Hstr")
+			if hstrRaw != "" {
+				hstr = &hstrRaw
+			}
+			if hstr != nil {
+				err = goa.MergeErrors(err, goa.ValidateFormat("hstr", *hstr, goa.FormatDateTime))
+			}
+			{
+				hint32Raw := resp.Header.Get("Goa-Attribute-Hint32")
+				if hint32Raw != "" {
+					v, err2 := strconv.ParseInt(hint32Raw, 10, 32)
+					if err2 != nil {
+						err = goa.MergeErrors(err, goa.InvalidFieldTypeError("hint32", hint32Raw, "integer"))
+					}
+					pv := int32(v)
+					hint32 = &pv
+				}
+			}
+			if hint32 != nil {
+				if *hint32 < 5 {
+					err = goa.MergeErrors(err, goa.InvalidRangeError("hint32", *hint32, 5, true))
+				}
+			}
+			if err != nil {
+				return nil, goahttp.ErrValidationError("ServiceUnmappedResultObjectValidate", "MethodUnmappedResultObjectValidate", err)
+			}
+			res := NewMethodUnmappedResultObjectValidateResultOK(hstr, hint32)
+			return res, nil
+		default:
+			body, _ := ioutil.ReadAll(resp.Body)
+			return nil, goahttp.ErrInvalidResponse("ServiceUnmappedResultObjectValidate", "MethodUnmappedResultObjectValidate", resp.StatusCode, string(body))
+		}
+	}
+}
+`
+
+var UnmappedResultObjectWithHeadersDecodeCode = `// DecodeMethodUnmappedResultObjectWithHeadersResponse returns a decoder for
+// responses returned by the ServiceUnmappedResultObjectWithHeaders
+// MethodUnmappedResultObjectWithHeaders endpoint. restoreBody controls whether
+// the response body should be restored after having been read.
+func DecodeMethodUnmappedResultObjectWithHeadersResponse(decoder func(*http.Response) goahttp.Decoder, restoreBody bool) func(*http.Response) (interface{}, error) {
+	return func(resp *http.Response) (interface{}, error) {
+		if restoreBody {
+			b, err := ioutil.ReadAll(resp.Body)
+			if err != nil {
+				return nil, err
+			}
+			resp.Body = ioutil.NopCloser(bytes.NewBuffer(b))
+			defer func() {
+				resp.Body = ioutil.NopCloser(bytes.NewBuffer(b))
+			}()
+		} else {
+			defer resp.Body.Close()
+		}
+		switch resp.StatusCode {
+		case http.StatusOK:
+			var (
+				hint32 *int32
+				hstr   *string
+				err    error
+			)
+			{
+				hint32Raw := resp.Header.Get("Location")
+				if hint32Raw != "" {
+					v, err2 := strconv.ParseInt(hint32Raw, 10, 32)
+					if err2 != nil {
+						err = goa.MergeErrors(err, goa.InvalidFieldTypeError("hint32", hint32Raw, "integer"))
+					}
+					pv := int32(v)
+					hint32 = &pv
+				}
+			}
+			hstrRaw := resp.Header.Get("Goa-Attribute-Hstr")
+			if hstrRaw != "" {
+				hstr = &hstrRaw
+			}
+			if err != nil {
+				return nil, goahttp.ErrValidationError("ServiceUnmappedResultObjectWithHeaders", "MethodUnmappedResultObjectWithHeaders", err)
+			}
+			res := NewMethodUnmappedResultObjectWithHeadersResultOK(hint32, hstr)
+			return res, nil
+		default:
+			body, _ := ioutil.ReadAll(resp.Body)
+			return nil, goahttp.ErrInvalidResponse("ServiceUnmappedResultObjectWithHeaders", "MethodUnmappedResultObjectWithHeaders", resp.StatusCode, string(body))
+		}
+	}
+}
+`
+
+var UnmappedResultPrimitiveDecodeCode = `// DecodeMethodUnmappedResultPrimitiveResponse returns a decoder for responses
+// returned by the ServiceUnmappedResultPrimitive MethodUnmappedResultPrimitive
+// endpoint. restoreBody controls whether the response body should be restored
+// after having been read.
+func DecodeMethodUnmappedResultPrimitiveResponse(decoder func(*http.Response) goahttp.Decoder, restoreBody bool) func(*http.Response) (interface{}, error) {
+	return func(resp *http.Response) (interface{}, error) {
+		if restoreBody {
+			b, err := ioutil.ReadAll(resp.Body)
+			if err != nil {
+				return nil, err
+			}
+			resp.Body = ioutil.NopCloser(bytes.NewBuffer(b))
+			defer func() {
+				resp.Body = ioutil.NopCloser(bytes.NewBuffer(b))
+			}()
+		} else {
+			defer resp.Body.Close()
+		}
+		switch resp.StatusCode {
+		case http.StatusOK:
+			var (
+				goaAttribute *float32
+				err          error
+			)
+			{
+				goaAttributeRaw := resp.Header.Get("Goa-Attribute")
+				if goaAttributeRaw != "" {
+					v, err2 := strconv.ParseFloat(goaAttributeRaw, 32)
+					if err2 != nil {
+						err = goa.MergeErrors(err, goa.InvalidFieldTypeError("goaAttribute", goaAttributeRaw, "float"))
+					}
+					pv := float32(v)
+					goaAttribute = &pv
+				}
+			}
+			if err != nil {
+				return nil, goahttp.ErrValidationError("ServiceUnmappedResultPrimitive", "MethodUnmappedResultPrimitive", err)
+			}
+			return goaAttribute, nil
+		default:
+			body, _ := ioutil.ReadAll(resp.Body)
+			return nil, goahttp.ErrInvalidResponse("ServiceUnmappedResultPrimitive", "MethodUnmappedResultPrimitive", resp.StatusCode, string(body))
+		}
+	}
+}
+`
+
+var UnmappedResultPrimitiveValidateDecodeCode = `// DecodeMethodUnmappedResultPrimitiveValidateResponse returns a decoder for
+// responses returned by the ServiceUnmappedResultPrimitiveValidate
+// MethodUnmappedResultPrimitiveValidate endpoint. restoreBody controls whether
+// the response body should be restored after having been read.
+func DecodeMethodUnmappedResultPrimitiveValidateResponse(decoder func(*http.Response) goahttp.Decoder, restoreBody bool) func(*http.Response) (interface{}, error) {
+	return func(resp *http.Response) (interface{}, error) {
+		if restoreBody {
+			b, err := ioutil.ReadAll(resp.Body)
+			if err != nil {
+				return nil, err
+			}
+			resp.Body = ioutil.NopCloser(bytes.NewBuffer(b))
+			defer func() {
+				resp.Body = ioutil.NopCloser(bytes.NewBuffer(b))
+			}()
+		} else {
+			defer resp.Body.Close()
+		}
+		switch resp.StatusCode {
+		case http.StatusOK:
+			var (
+				goaAttribute *float32
+				err          error
+			)
+			{
+				goaAttributeRaw := resp.Header.Get("Goa-Attribute")
+				if goaAttributeRaw != "" {
+					v, err2 := strconv.ParseFloat(goaAttributeRaw, 32)
+					if err2 != nil {
+						err = goa.MergeErrors(err, goa.InvalidFieldTypeError("goaAttribute", goaAttributeRaw, "float"))
+					}
+					pv := float32(v)
+					goaAttribute = &pv
+				}
+			}
+			if goaAttribute != nil {
+				if *goaAttribute > 5 {
+					err = goa.MergeErrors(err, goa.InvalidRangeError("goaAttribute", *goaAttribute, 5, false))
+				}
+			}
+			if err != nil {
+				return nil, goahttp.ErrValidationError("ServiceUnmappedResultPrimitiveValidate", "MethodUnmappedResultPrimitiveValidate", err)
+			}
+			return goaAttribute, nil
+		default:
+			body, _ := ioutil.ReadAll(resp.Body)
+			return nil, goahttp.ErrInvalidResponse("ServiceUnmappedResultPrimitiveValidate", "MethodUnmappedResultPrimitiveValidate", resp.StatusCode, string(body))
+		}
+	}
+}
+`
+
+var UnmappedResultPrimitiveWithHeadersDecodeCode = `// DecodeMethodUnmappedResultPrimitiveWithHeadersResponse returns a decoder
+// for responses returned by the ServiceUnmappedResultPrimitiveWithHeaders
+// MethodUnmappedResultPrimitiveWithHeaders endpoint. restoreBody controls
+// whether the response body should be restored after having been read.
+func DecodeMethodUnmappedResultPrimitiveWithHeadersResponse(decoder func(*http.Response) goahttp.Decoder, restoreBody bool) func(*http.Response) (interface{}, error) {
+	return func(resp *http.Response) (interface{}, error) {
+		if restoreBody {
+			b, err := ioutil.ReadAll(resp.Body)
+			if err != nil {
+				return nil, err
+			}
+			resp.Body = ioutil.NopCloser(bytes.NewBuffer(b))
+			defer func() {
+				resp.Body = ioutil.NopCloser(bytes.NewBuffer(b))
+			}()
+		} else {
+			defer resp.Body.Close()
+		}
+		switch resp.StatusCode {
+		case http.StatusOK:
+			var (
+				location interface{}
+				err      error
+			)
+			locationRaw := resp.Header.Get("Location")
+			if locationRaw == "" {
+				err = goa.MergeErrors(err, goa.MissingFieldError("Location", "header"))
+			}
+			location = locationRaw
+			if err != nil {
+				return nil, goahttp.ErrValidationError("ServiceUnmappedResultPrimitiveWithHeaders", "MethodUnmappedResultPrimitiveWithHeaders", err)
+			}
+			return location, nil
+		default:
+			body, _ := ioutil.ReadAll(resp.Body)
+			return nil, goahttp.ErrInvalidResponse("ServiceUnmappedResultPrimitiveWithHeaders", "MethodUnmappedResultPrimitiveWithHeaders", resp.StatusCode, string(body))
+		}
+	}
+}
+`
+
+var UnmappedResultArrayDecodeCode = `// DecodeMethodUnmappedResultArrayResponse returns a decoder for responses
+// returned by the ServiceUnmappedResultArray MethodUnmappedResultArray
+// endpoint. restoreBody controls whether the response body should be restored
+// after having been read.
+func DecodeMethodUnmappedResultArrayResponse(decoder func(*http.Response) goahttp.Decoder, restoreBody bool) func(*http.Response) (interface{}, error) {
+	return func(resp *http.Response) (interface{}, error) {
+		if restoreBody {
+			b, err := ioutil.ReadAll(resp.Body)
+			if err != nil {
+				return nil, err
+			}
+			resp.Body = ioutil.NopCloser(bytes.NewBuffer(b))
+			defer func() {
+				resp.Body = ioutil.NopCloser(bytes.NewBuffer(b))
+			}()
+		} else {
+			defer resp.Body.Close()
+		}
+		switch resp.StatusCode {
+		case http.StatusOK:
+			var (
+				goaAttribute []uint
+				err          error
+			)
+			{
+				goaAttributeRaw := resp.Header["Goa-Attribute"]
+
+				if goaAttributeRaw != nil {
+					goaAttribute = make([]uint, len(goaAttributeRaw))
+					for i, rv := range goaAttributeRaw {
+						v, err2 := strconv.ParseUint(rv, 10, strconv.IntSize)
+						if err2 != nil {
+							err = goa.MergeErrors(err, goa.InvalidFieldTypeError("goaAttribute", goaAttributeRaw, "array of unsigned integers"))
+						}
+						goaAttribute[i] = uint(v)
+					}
+				}
+			}
+			if err != nil {
+				return nil, goahttp.ErrValidationError("ServiceUnmappedResultArray", "MethodUnmappedResultArray", err)
+			}
+			return goaAttribute, nil
+		default:
+			body, _ := ioutil.ReadAll(resp.Body)
+			return nil, goahttp.ErrInvalidResponse("ServiceUnmappedResultArray", "MethodUnmappedResultArray", resp.StatusCode, string(body))
+		}
+	}
+}
+`
+
+var UnmappedResultArrayValidateDecodeCode = `// DecodeMethodUnmappedResultArrayValidateResponse returns a decoder for
+// responses returned by the ServiceUnmappedResultArrayValidate
+// MethodUnmappedResultArrayValidate endpoint. restoreBody controls whether the
+// response body should be restored after having been read.
+func DecodeMethodUnmappedResultArrayValidateResponse(decoder func(*http.Response) goahttp.Decoder, restoreBody bool) func(*http.Response) (interface{}, error) {
+	return func(resp *http.Response) (interface{}, error) {
+		if restoreBody {
+			b, err := ioutil.ReadAll(resp.Body)
+			if err != nil {
+				return nil, err
+			}
+			resp.Body = ioutil.NopCloser(bytes.NewBuffer(b))
+			defer func() {
+				resp.Body = ioutil.NopCloser(bytes.NewBuffer(b))
+			}()
+		} else {
+			defer resp.Body.Close()
+		}
+		switch resp.StatusCode {
+		case http.StatusOK:
+			var (
+				goaAttribute []uint
+				err          error
+			)
+			{
+				goaAttributeRaw := resp.Header["Goa-Attribute"]
+
+				if goaAttributeRaw != nil {
+					goaAttribute = make([]uint, len(goaAttributeRaw))
+					for i, rv := range goaAttributeRaw {
+						v, err2 := strconv.ParseUint(rv, 10, strconv.IntSize)
+						if err2 != nil {
+							err = goa.MergeErrors(err, goa.InvalidFieldTypeError("goaAttribute", goaAttributeRaw, "array of unsigned integers"))
+						}
+						goaAttribute[i] = uint(v)
+					}
+				}
+			}
+			if len(goaAttribute) < 10 {
+				err = goa.MergeErrors(err, goa.InvalidLengthError("goaAttribute", goaAttribute, len(goaAttribute), 10, true))
+			}
+			if err != nil {
+				return nil, goahttp.ErrValidationError("ServiceUnmappedResultArrayValidate", "MethodUnmappedResultArrayValidate", err)
+			}
+			return goaAttribute, nil
+		default:
+			body, _ := ioutil.ReadAll(resp.Body)
+			return nil, goahttp.ErrInvalidResponse("ServiceUnmappedResultArrayValidate", "MethodUnmappedResultArrayValidate", resp.StatusCode, string(body))
+		}
+	}
+}
+`
+
+var UnmappedResultArrayWithHeadersDecodeCode = `// DecodeMethodUnmappedResultArrayWithHeadersResponse returns a decoder for
+// responses returned by the ServiceUnmappedResultArrayWithHeaders
+// MethodUnmappedResultArrayWithHeaders endpoint. restoreBody controls
+// whether the response body should be restored after having been read.
+func DecodeMethodUnmappedResultArrayWithHeadersResponse(decoder func(*http.Response) goahttp.Decoder, restoreBody bool) func(*http.Response) (interface{}, error) {
+	return func(resp *http.Response) (interface{}, error) {
+		if restoreBody {
+			b, err := ioutil.ReadAll(resp.Body)
+			if err != nil {
+				return nil, err
+			}
+			resp.Body = ioutil.NopCloser(bytes.NewBuffer(b))
+			defer func() {
+				resp.Body = ioutil.NopCloser(bytes.NewBuffer(b))
+			}()
+		} else {
+			defer resp.Body.Close()
+		}
+		switch resp.StatusCode {
+		case http.StatusOK:
+			var (
+				location []string
+				err      error
+			)
+			location = resp.Header["Location"]
+
+			if location == nil {
+				err = goa.MergeErrors(err, goa.MissingFieldError("Location", "header"))
+			}
+			if err != nil {
+				return nil, goahttp.ErrValidationError("ServiceUnmappedResultArrayWithHeaders", "MethodUnmappedResultArrayWithHeaders", err)
+			}
+			return location, nil
+		default:
+			body, _ := ioutil.ReadAll(resp.Body)
+			return nil, goahttp.ErrInvalidResponse("ServiceUnmappedResultArrayWithHeaders", "MethodUnmappedResultArrayWithHeaders", resp.StatusCode, string(body))
+		}
+	}
+}
+`
diff --git a/http/codegen/testdata/result_dsls.go b/http/codegen/testdata/result_dsls.go
index 36d4b264..45b611c1 100644
--- a/http/codegen/testdata/result_dsls.go
+++ b/http/codegen/testdata/result_dsls.go
@@ -750,16 +750,11 @@ var EmptyErrorResponseBodyDSL = func() {
 			Error("internal_error")
 			Error("not_found", String)
 			HTTP(func() {
-				POST("/")
+				HEAD("/")
 				Response(StatusOK)
 				Response("internal_error", StatusInternalServerError, func() {
 					Body(Empty)
 					Header("name:Error-Name")
-					Header("id:Error-ID")
-					Header("message:Error-message")
-					Header("fault:Error-Fault")
-					Header("temporary:Error-Temporary")
-					Header("timeout:Error-Timeout")
 				})
 				Response("not_found", StatusNotFound, func() {
 					Body(Empty)
@@ -1282,6 +1277,139 @@ var EmptyServerResponseWithTagsDSL = func() {
 	})
 }
 
+var UnmappedResultObjectDSL = func() {
+	Service("ServiceUnmappedResultObject", func() {
+		Method("MethodUnmappedResultObject", func() {
+			Result(func() {
+				Attribute("hstr", String)
+				Attribute("hint32", Int32)
+			})
+			HTTP(func() {
+				POST("/")
+				Response(StatusOK, func() {
+					Body(Empty)
+				})
+			})
+		})
+	})
+}
+
+var UnmappedResultObjectWithBodyDSL = func() {
+	Service("ServiceUnmappedResultObjectWithBody", func() {
+		Method("MethodUnmappedResultObjectWithBody", func() {
+			Result(func() {
+				Attribute("hstr", String)
+				Attribute("hint32", Int32)
+			})
+			HTTP(func() {
+				POST("/")
+				Response(StatusOK, func() {
+					Body("hstr")
+				})
+			})
+		})
+	})
+}
+
+var UnmappedResultObjectValidateDSL = func() {
+	Service("ServiceUnmappedResultObjectValidate", func() {
+		Method("MethodUnmappedResultObjectValidate", func() {
+			Result(func() {
+				Attribute("hstr", String, func() {
+					Format(FormatDateTime)
+				})
+				Attribute("hint32", Int32, func() {
+					Minimum(5)
+				})
+			})
+			HTTP(func() {
+				DELETE("/")
+				Response(StatusOK, func() {
+					Body(Empty)
+				})
+			})
+		})
+	})
+}
+
+var UnmappedResultObjectWithHeadersDSL = func() {
+	Service("ServiceUnmappedResultObjectWithHeaders", func() {
+		Method("MethodUnmappedResultObjectWithHeaders", func() {
+			Result(func() {
+				Attribute("hstr", String)
+				Attribute("hint32", Int32)
+			})
+			HTTP(func() {
+				HEAD("/")
+				Response(StatusOK, func() {
+					Body(Empty)
+					Header("hint32:Location")
+				})
+			})
+		})
+	})
+}
+
+var UnmappedResultPrimitiveDSL = func() {
+	Service("ServiceUnmappedResultPrimitive", func() {
+		Method("MethodUnmappedResultPrimitive", func() {
+			Result(Float32)
+			HTTP(func() {
+				HEAD("/")
+				Response(StatusOK, func() {
+					Body(Empty)
+				})
+			})
+		})
+	})
+}
+
+var UnmappedResultPrimitiveValidateDSL = func() {
+	Service("ServiceUnmappedResultPrimitiveValidate", func() {
+		Method("MethodUnmappedResultPrimitiveValidate", func() {
+			Result(Float32, func() {
+				Maximum(5.0)
+			})
+			HTTP(func() {
+				GET("/")
+				Response(StatusOK, func() {
+					Body(Empty)
+				})
+			})
+		})
+	})
+}
+
+var UnmappedResultArrayDSL = func() {
+	Service("ServiceUnmappedResultArray", func() {
+		Method("MethodUnmappedResultArray", func() {
+			Result(ArrayOf(UInt))
+			HTTP(func() {
+				POST("/")
+				Response(StatusOK, func() {
+					Body(Empty)
+				})
+			})
+		})
+	})
+}
+
+var UnmappedResultArrayValidateDSL = func() {
+	Service("ServiceUnmappedResultArrayValidate", func() {
+		Method("MethodUnmappedResultArrayValidate", func() {
+			Result(ArrayOf(UInt), func() {
+				MinLength(10)
+			})
+			HTTP(func() {
+				OPTIONS("/")
+				Response(StatusOK, func() {
+					Body(Empty)
+				})
+			})
+		})
+	})
+}
+
 var ResultHeaderStringImplicitDSL = func() {
 	Service("ServiceHeaderStringImplicit", func() {
 		Method("MethodHeaderStringImplicit", func() {
diff --git a/http/codegen/testdata/result_encode_functions.go b/http/codegen/testdata/result_encode_functions.go
index ca3a82a5..70638086 100644
--- a/http/codegen/testdata/result_encode_functions.go
+++ b/http/codegen/testdata/result_encode_functions.go
@@ -442,9 +442,11 @@ var ResultHeaderBoolDefaultEncodeCode = `// EncodeMethodHeaderBoolDefaultRespons
 func EncodeMethodHeaderBoolDefaultResponse(encoder func(context.Context, http.ResponseWriter) goahttp.Encoder) func(context.Context, http.ResponseWriter, interface{}) error {
 	return func(ctx context.Context, w http.ResponseWriter, v interface{}) error {
 		res, _ := v.(*serviceheaderbooldefault.MethodHeaderBoolDefaultResult)
-		val := res.H
-		hs := strconv.FormatBool(val)
-		w.Header().Set("H", hs)
+		{
+			val := res.H
+			hs := strconv.FormatBool(val)
+			w.Header().Set("H", hs)
+		}
 		w.WriteHeader(http.StatusOK)
 		return nil
 	}
@@ -457,9 +459,11 @@ var ResultHeaderBoolRequiredDefaultEncodeCode = `// EncodeMethodHeaderBoolRequir
 func EncodeMethodHeaderBoolRequiredDefaultResponse(encoder func(context.Context, http.ResponseWriter) goahttp.Encoder) func(context.Context, http.ResponseWriter, interface{}) error {
 	return func(ctx context.Context, w http.ResponseWriter, v interface{}) error {
 		res, _ := v.(*serviceheaderboolrequireddefault.MethodHeaderBoolRequiredDefaultResult)
-		val := res.H
-		hs := strconv.FormatBool(val)
-		w.Header().Set("H", hs)
+		{
+			val := res.H
+			hs := strconv.FormatBool(val)
+			w.Header().Set("H", hs)
+		}
 		w.WriteHeader(http.StatusOK)
 		return nil
 	}
@@ -684,6 +688,12 @@ func EncodeMethodEmptyBodyResultMultipleViewResponse(encoder func(context.Contex
 		if res.Projected.C != nil {
 			w.Header().Set("Location", *res.Projected.C)
 		}
+		if res.Projected.A != nil {
+			w.Header().Set("Goa-Attribute-A", *res.Projected.A)
+		}
+		if res.Projected.B != nil {
+			w.Header().Set("Goa-Attribute-B", *res.Projected.B)
+		}
 		w.WriteHeader(http.StatusOK)
 		return nil
 	}
@@ -729,6 +739,9 @@ func EncodeMethodExplicitBodyPrimitiveResultMultipleViewResponse(encoder func(co
 		if res.Projected.C != nil {
 			w.Header().Set("Location", *res.Projected.C)
 		}
+		if res.Projected.B != nil {
+			w.Header().Set("Goa-Attribute-B", *res.Projected.B)
+		}
 		w.WriteHeader(http.StatusOK)
 		return enc.Encode(body)
 	}
@@ -747,6 +760,9 @@ func EncodeMethodExplicitBodyUserResultMultipleViewResponse(encoder func(context
 		if res.Projected.C != nil {
 			w.Header().Set("Location", *res.Projected.C)
 		}
+		if res.Projected.B != nil {
+			w.Header().Set("Goa-Attribute-B", *res.Projected.B)
+		}
 		w.WriteHeader(http.StatusOK)
 		return enc.Encode(body)
 	}
@@ -997,6 +1013,8 @@ var EmptyServerResponseEncodeCode = `// EncodeMethodEmptyServerResponseResponse
 // endpoint.
 func EncodeMethodEmptyServerResponseResponse(encoder func(context.Context, http.ResponseWriter) goahttp.Encoder) func(context.Context, http.ResponseWriter, interface{}) error {
 	return func(ctx context.Context, w http.ResponseWriter, v interface{}) error {
+		res, _ := v.(*serviceemptyserverresponse.MethodEmptyServerResponseResult)
+		w.Header().Set("Goa-Attribute-H", res.H)
 		w.WriteHeader(http.StatusOK)
 		return nil
 	}
@@ -1013,8 +1031,201 @@ func EncodeMethodEmptyServerResponseWithTagsResponse(encoder func(context.Contex
 			w.WriteHeader(http.StatusNotModified)
 			return nil
 		}
+		w.Header().Set("Goa-Attribute-H", res.H)
 		w.WriteHeader(http.StatusNoContent)
 		return nil
 	}
 }
 `
+
+var UnmappedResultObjectEncodeCode = `// EncodeMethodUnmappedResultObjectResponse returns an encoder for responses
+// returned by the ServiceUnmappedResultObject MethodUnmappedResultObject
+// endpoint.
+func EncodeMethodUnmappedResultObjectResponse(encoder func(context.Context, http.ResponseWriter) goahttp.Encoder) func(context.Context, http.ResponseWriter, interface{}) error {
+	return func(ctx context.Context, w http.ResponseWriter, v interface{}) error {
+		res, _ := v.(*serviceunmappedresultobject.MethodUnmappedResultObjectResult)
+		if res.Hstr != nil {
+			w.Header().Set("Goa-Attribute-Hstr", *res.Hstr)
+		}
+		if res.Hint32 != nil {
+			val := res.Hint32
+			hint32s := strconv.FormatInt(int64(*val), 10)
+			w.Header().Set("Goa-Attribute-Hint32", hint32s)
+		}
+		w.WriteHeader(http.StatusOK)
+		return nil
+	}
+}
+`
+
+var UnmappedResultObjectWithBodyEncodeCode = `// EncodeMethodUnmappedResultObjectWithBodyResponse returns an encoder for
+// responses returned by the ServiceUnmappedResultObjectWithBody
+// MethodUnmappedResultObjectWithBody endpoint.
+func EncodeMethodUnmappedResultObjectWithBodyResponse(encoder func(context.Context, http.ResponseWriter) goahttp.Encoder) func(context.Context, http.ResponseWriter, interface{}) error {
+	return func(ctx context.Context, w http.ResponseWriter, v interface{}) error {
+		res, _ := v.(*serviceunmappedresultobjectwithbody.MethodUnmappedResultObjectWithBodyResult)
+		enc := encoder(ctx, w)
+		body := res.Hstr
+		if res.Hint32 != nil {
+			val := res.Hint32
+			hint32s := strconv.FormatInt(int64(*val), 10)
+			w.Header().Set("Goa-Attribute-Hint32", hint32s)
+		}
+		w.WriteHeader(http.StatusOK)
+		return enc.Encode(body)
+	}
+}
+`
+
+var UnmappedResultObjectValidateEncodeCode = `// EncodeMethodUnmappedResultObjectValidateResponse returns an encoder for
+// responses returned by the ServiceUnmappedResultObjectValidate
+// MethodUnmappedResultObjectValidate endpoint.
+func EncodeMethodUnmappedResultObjectValidateResponse(encoder func(context.Context, http.ResponseWriter) goahttp.Encoder) func(context.Context, http.ResponseWriter, interface{}) error {
+	return func(ctx context.Context, w http.ResponseWriter, v interface{}) error {
+		res, _ := v.(*serviceunmappedresultobjectvalidate.MethodUnmappedResultObjectValidateResult)
+		if res.Hstr != nil {
+			w.Header().Set("Goa-Attribute-Hstr", *res.Hstr)
+		}
+		if res.Hint32 != nil {
+			val := res.Hint32
+			hint32s := strconv.FormatInt(int64(*val), 10)
+			w.Header().Set("Goa-Attribute-Hint32", hint32s)
+		}
+		w.WriteHeader(http.StatusOK)
+		return nil
+	}
+}
+`
+
+var UnmappedResultObjectWithHeadersEncodeCode = `// EncodeMethodUnmappedResultObjectWithHeadersResponse returns an encoder for
+// responses returned by the ServiceUnmappedResultObjectWithHeaders
+// MethodUnmappedResultObjectWithHeaders endpoint.
+func EncodeMethodUnmappedResultObjectWithHeadersResponse(encoder func(context.Context, http.ResponseWriter) goahttp.Encoder) func(context.Context, http.ResponseWriter, interface{}) error {
+	return func(ctx context.Context, w http.ResponseWriter, v interface{}) error {
+		res, _ := v.(*serviceunmappedresultobjectwithheaders.MethodUnmappedResultObjectWithHeadersResult)
+		if res.Hint32 != nil {
+			val := res.Hint32
+			hint32s := strconv.FormatInt(int64(*val), 10)
+			w.Header().Set("Location", hint32s)
+		}
+		if res.Hstr != nil {
+			w.Header().Set("Goa-Attribute-Hstr", *res.Hstr)
+		}
+		w.WriteHeader(http.StatusOK)
+		return nil
+	}
+}
+`
+
+var UnmappedResultPrimitiveEncodeCode = `// EncodeMethodUnmappedResultPrimitiveResponse returns an encoder for responses
+// returned by the ServiceUnmappedResultPrimitive MethodUnmappedResultPrimitive
+// endpoint.
+func EncodeMethodUnmappedResultPrimitiveResponse(encoder func(context.Context, http.ResponseWriter) goahttp.Encoder) func(context.Context, http.ResponseWriter, interface{}) error {
+	return func(ctx context.Context, w http.ResponseWriter, v interface{}) error {
+		res, _ := v.(float32)
+		{
+			val := res
+			goaAttributes := strconv.FormatFloat(float64(val), 'f', -1, 32)
+			w.Header().Set("Goa-Attribute", goaAttributes)
+		}
+		w.WriteHeader(http.StatusOK)
+		return nil
+	}
+}
+`
+
+var UnmappedResultPrimitiveValidateEncodeCode = `// EncodeMethodUnmappedResultPrimitiveValidateResponse returns an encoder for
+// responses returned by the ServiceUnmappedResultPrimitiveValidate
+// MethodUnmappedResultPrimitiveValidate endpoint.
+func EncodeMethodUnmappedResultPrimitiveValidateResponse(encoder func(context.Context, http.ResponseWriter) goahttp.Encoder) func(context.Context, http.ResponseWriter, interface{}) error {
+	return func(ctx context.Context, w http.ResponseWriter, v interface{}) error {
+		res, _ := v.(float32)
+		{
+			val := res
+			goaAttributes := strconv.FormatFloat(float64(val), 'f', -1, 32)
+			w.Header().Set("Goa-Attribute", goaAttributes)
+		}
+		w.WriteHeader(http.StatusOK)
+		return nil
+	}
+}
+`
+
+var UnmappedResultPrimitiveWithHeadersEncodeCode = `// EncodeMethodUnmappedResultPrimitiveWithHeadersResponse returns an
+// encoder for responses returned by the
+// ServiceUnmappedResultPrimitiveWithHeaders
+// MethodUnmappedResultPrimitiveWithHeaders endpoint.
+func EncodeMethodUnmappedResultPrimitiveWithHeadersResponse(encoder func(context.Context, http.ResponseWriter) goahttp.Encoder) func(context.Context, http.ResponseWriter, interface{}) error {
+	return func(ctx context.Context, w http.ResponseWriter, v interface{}) error {
+		res, _ := v.(interface{})
+		if res != nil {
+			val := res
+			locations := fmt.Sprintf("%v", val)
+			w.Header().Set("Location", locations)
+		}
+		w.WriteHeader(http.StatusOK)
+		return nil
+	}
+}
+`
+
+var UnmappedResultArrayEncodeCode = `// EncodeMethodUnmappedResultArrayResponse returns an encoder for responses
+// returned by the ServiceUnmappedResultArray MethodUnmappedResultArray
+// endpoint.
+func EncodeMethodUnmappedResultArrayResponse(encoder func(context.Context, http.ResponseWriter) goahttp.Encoder) func(context.Context, http.ResponseWriter, interface{}) error {
+	return func(ctx context.Context, w http.ResponseWriter, v interface{}) error {
+		res, _ := v.([]uint)
+		if res != nil {
+			val := res
+			goaAttributesSlice := make([]string, len(val))
+			for i, e := range val {
+				es := strconv.FormatUint(uint64(e), 10)
+				goaAttributesSlice[i] = es
+			}
+			goaAttributes := strings.Join(goaAttributesSlice, ", ")
+			w.Header().Set("Goa-Attribute", goaAttributes)
+		}
+		w.WriteHeader(http.StatusOK)
+		return nil
+	}
+}
+`
+
+var UnmappedResultArrayValidateEncodeCode = `// EncodeMethodUnmappedResultArrayValidateResponse returns an encoder for
+// responses returned by the ServiceUnmappedResultArrayValidate
+// MethodUnmappedResultArrayValidate endpoint.
+func EncodeMethodUnmappedResultArrayValidateResponse(encoder func(context.Context, http.ResponseWriter) goahttp.Encoder) func(context.Context, http.ResponseWriter, interface{}) error {
+	return func(ctx context.Context, w http.ResponseWriter, v interface{}) error {
+		res, _ := v.([]uint)
+		if res != nil {
+			val := res
+			goaAttributesSlice := make([]string, len(val))
+			for i, e := range val {
+				es := strconv.FormatUint(uint64(e), 10)
+				goaAttributesSlice[i] = es
+			}
+			goaAttributes := strings.Join(goaAttributesSlice, ", ")
+			w.Header().Set("Goa-Attribute", goaAttributes)
+		}
+		w.WriteHeader(http.StatusOK)
+		return nil
+	}
+}
+`
+
+var UnmappedResultArrayWithHeadersEncodeCode = `// EncodeMethodUnmappedResultArrayWithHeadersResponse returns an encoder
+// for responses returned by the ServiceUnmappedResultArrayWithHeaders
+// MethodUnmappedResultArrayWithHeaders endpoint.
+func EncodeMethodUnmappedResultArrayWithHeadersResponse(encoder func(context.Context, http.ResponseWriter) goahttp.Encoder) func(context.Context, http.ResponseWriter, interface{}) error {
+	return func(ctx context.Context, w http.ResponseWriter, v interface{}) error {
+		res, _ := v.([]string)
+		if res != nil {
+			val := res
+			locations := strings.Join(val, ", ")
+			w.Header().Set("Location", locations)
+		}
+		w.WriteHeader(http.StatusOK)
+		return nil
+	}
+}
+`