goadesign / goa

🌟 Goa: Elevate Go API development! 🚀 Streamlined design, automatic code generation, and seamless HTTP/gRPC support. ✨
https://goa.design
MIT License
5.68k stars 559 forks source link

Is Reference keyword working with simple Types in other simple Types? #1056

Closed dtrehas closed 7 years ago

dtrehas commented 7 years ago

I had a case that I needed to use a Type Reference in a simple(not Media) Type.

During the code generation the Attribute that was referenced had restriction in the original type but the generated code in the more complex type did not incorporated the validation checks.

In other cases (not included) the referenced type had an integer attribute but when it was referenced in the more complex type the Attribute was only string.

So is it safe to conclude that by referencing a Type in other Type, validations, descriptions and attribute types(int, string, ...) are not respected?

Is this by design?

Pay attention to "vat" field in design and code generated user_type Unfortunately i can not make it seem nice in this preview. Copy the code please in a normal code editor.

// VatType is the unique number identifying a company var VatType= Type("VatType", func() { // TODO regexp with VAT Attribute("vat", String, "Is the the unique tax number identifying a company", func() { MinLength(5) MaxLength(9) Pattern("[^[0-9]([a-zA-Z ]+)]") }) })

// CountryType identifier using only 2 letters var CountryType = Type("CountryType", func() { Attribute("country", String, "Country described in only 2 letters") //TODO Regexp with Country })

//PasswordType is be used as reference for passwords var PasswordType = Type("PasswordType", func() { //TODO Password check Attribute("Password", String, "Password has to have 6+ letters, symbols,digits") })

// Company details contain all necessary details var Company = Type("Company", func() { Reference(VatType) // No use in validation checks in generated user_type code Reference(CountryType) Reference(PasswordType)

Attribute("vat")
Attribute("doy", String, "Tax service where this company is registered to")
Attribute("name", String, "Company name")
Attribute("road", String, "Road and number")
Attribute("city", String, "City")
Attribute("postalcode", String, "Postal code")

Attribute("country")
Attribute("phone", String, "Land line")
Attribute("cell", String, "Cell phone number")
Attribute("email", String, "Company e-mail ", func() {
    Format("email")

})
Attribute("fullname", String, "Contact person full name details")
Attribute("password")

})

//Rfq stands for Request for Quotation var Rfq = MediaType("application/vnd.rfq+json", func() { Description("Request for quotation details") Attributes(func() { Reference(Company) Attribute("vat") Attribute("id", String, "Request for quotation ID") Attribute("submitted", DateTime, "What time was submitted") Attribute("expires", DateTime, "When the request for quotations expires ") Attribute("import", Boolean, "Import (true) or Export (false)") Attribute("transtype", String, "Connex, Groupage or Truck", func() { Enum("connex", "groupage", "truck") // TODO Number? }) Attribute("fce", String, "FOB, CIF, EXW transportation", func() { Enum("fob", "cif", "exw") })

    //  // Bidding, Pending,Ended, Cancelled

    Attribute("status", Integer, "Bidding, Pending, Ended, Cancelled")
    Attribute("notes", String, "Notes for this request")
})

View("default", func() { // View defines a rendering of the media type.
    Attribute("id")
    Attribute("submitted")
    Attribute("import")
    Attribute("status")
})

View("extended", func() {
    Attribute("vat")
    Attribute("id")
    Attribute("submitted")

    Attribute("import")
    Attribute("status")
})

})

//Generated code in user_types

// Company user type. type Company struct { // Cell phone number Cell string form:"cell,omitempty" json:"cell,omitempty" xml:"cell,omitempty" // City City string form:"city,omitempty" json:"city,omitempty" xml:"city,omitempty" Country string form:"country,omitempty" json:"country,omitempty" xml:"country,omitempty" // Tax service where this company is registered to Doy string form:"doy,omitempty" json:"doy,omitempty" xml:"doy,omitempty" // Company e-mail Email string form:"email,omitempty" json:"email,omitempty" xml:"email,omitempty" // Contact person full name details Fullname string form:"fullname,omitempty" json:"fullname,omitempty" xml:"fullname,omitempty" // Company name Name string form:"name,omitempty" json:"name,omitempty" xml:"name,omitempty" Password string form:"password,omitempty" json:"password,omitempty" xml:"password,omitempty" // Land line Phone string form:"phone,omitempty" json:"phone,omitempty" xml:"phone,omitempty" // Postal code Postalcode string form:"postalcode,omitempty" json:"postalcode,omitempty" xml:"postalcode,omitempty" // Road and number Road string form:"road,omitempty" json:"road,omitempty" xml:"road,omitempty" Vat string form:"vat,omitempty" json:"vat,omitempty" xml:"vat,omitempty" }

// Validate validates the Company type instance. func (ut Company) Validate() (err error) { if ut.Email != nil { if err2 := goa.ValidateFormat(goa.FormatEmail, ut.Email); err2 != nil { err = goa.MergeErrors(err, goa.InvalidFormatError(response.email, *ut.Email, goa.FormatEmail, err2)) } } return

raphael commented 7 years ago

The problem here is that a type may only reference one other type. I'm closing this report as it works as expected. Feel free to open a feature request for supporting multiple reference types.