goadesign / goadesign/goa

struct:field:type meta causes compile error in generated encode_decode.go when used on HTTP path/query parameter fields

Open
#3,924 2 comments 0 reactions 0 assignees View on GitHub
Dominant language
Go
Stars
6.1k
Forks
583
Avg merge
2d 10h
Merged PRs (30d)
15

Description

When `struct:field:type` is used on a field that is read from HTTP path/query parameters, the generated encode_decode.go assigns the raw string directly to the typed field without conversion, causing a compile error.

The fix for this could be implemented generically by generating a parse step that invokes a user-provided conversion function, or for well known types (such as uuid.UUID from github.com/google/uuid) it can handle the conversion internally.

To reproduce:

```
var UUIDField = func() {
Format(FormatUUID)
Meta("struct:field:type", "uuid.UUID", "github.com/google/uuid")
}

var MyCriteria = Type("MyCriteria", func() {
Attribute("product_id", String, "Product identifier", func() { UUIDField() })
Attribute("other_product_id", String, "Other Product identifier", func() { UUIDField() })

Required("product_id", "other_product_id")
})

Method("do_something_with_products", func() {
Payload(MyCriteria)
HTTP(func() {
POST("/v1/product/{product_id}/dosomething")
Response(StatusOK)
Response(StatusUnauthorized)
Response(StatusInternalServerError)
Response(StatusBadRequest)
})
})
```

This is the generated code snippet from the service's encode_decode.go:

```
var (
productID uuid.UUID

params = mux.Vars(r)
)
productID = params["product_id"]
err = goa.MergeErrors(err, goa.ValidateFormat("product_id", productID, goa.FormatUUID))
```

The generated code should instead perform the type conversion before assignment, e.g:

```
var (
productIDRaw string
productID uuid.UUID
params = mux.Vars(r)
)
productIDRaw = params["product_id"]
err = goa.MergeErrors(err, goa.ValidateFormat("product_id", productIDRaw, goa.FormatUUID))
if err == nil {
productID, err = uuid.Parse(productIDRaw)
}
```

**Note:** this affects both path parameters (read via mux.Vars) and query parameters (read via `url.Values.Get`), wherever `struct:field:type` is used on a field that is decoded from the HTTP transport layer rather than from a JSON request body.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.