Skip to content

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

@sbryzak

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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions