Skip to content

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

Description

@sbryzak

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions