Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ConvertTo or CreateForm with constructor, factory or builder? #3581

Open
game013 opened this issue Aug 26, 2024 · 2 comments
Open

ConvertTo or CreateForm with constructor, factory or builder? #3581

game013 opened this issue Aug 26, 2024 · 2 comments

Comments

@game013
Copy link

game013 commented Aug 26, 2024

Hi!

I’ve recently started developing with Goa, and I’m still learning about all its functionalities. I’m currently trying to convert a user-defined type into a struct in a library. For this specific example, I want to handle a currency code and amount, using the currency library for internal representation.

Here’s the code I’ve implemented so far. However, I noticed that the library internally uses private fields and only exposes constructors to create the Amount object:

var CurrencyType = Type("Currency", func() {
	Description("Currency amount")
	TypeName("CurrencyType")
	ConvertTo(domain.Currency{})
	Attribute("currencyCode", String, "Currency code in ISO 4217", func() {
		Pattern(`^[A-Z]{3}$`)
		Example("USD")
		MaxLength(3)
		MinLength(3)
	})
	Attribute("number", String, "Amount of currency", func() {
		Pattern(`^\d+(\.\d{1,6})?$`)
		Example("1234.56")
	})
	Required("currencyCode", "number")
})

The constructor provided by the library, which I find useful, is:

func NewAmount(n, currencyCode string) (Amount, error)

It’s straightforward to implement the conversion for the CurrencyType field in my own packages. However, when CurrencyType is part of a more complex user-defined type, I’m unsure how to specify the constructor instead of directly mapping fields during the conversion.

My question is: Is there a way to parameterize the constructor to map a specific field when using ConvertTo?

@raphael
Copy link
Member

raphael commented Sep 5, 2024

Hello! There isn't currently a way to specify a constructor. A typical pattern used in similar situations is to add helper functions to the service methods that translate the data structures between the endpoint layer and the business logic / data layer.

@game013
Copy link
Author

game013 commented Sep 5, 2024

Thanks a lot for the answer. I was looking for a workaround and found an alternative solution. I defined the field using the struct:field:type meta tag, and it worked:

Attribute("cost", Any, "Product cost", func() {
	Meta("struct:field:type", "currency.Amount", "github.com/bojanz/currency")
})

However, I lost the ability to define the internal structure, even though the type has marshaling and unmarshaling methods. I tried using a custom-defined type, but when I do that, the meta tag behavior is ignored. I’m not sure if it’s intended to work this way or not.

It would be great if we could use custom definitions that are mapped to a custom type.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants
@raphael @game013 and others