So I have a LineItem
struct that contains a Price property that needs to be exported for SQLx to set the value from the database but the desired value requires logic to be applied to get the value (e.g. when LineItem.Refunded = true then LineItem.Price = 0.00 even if it's not $0.00 in the DB).
I don't want the property to be manually pulled / adjusted so I want to create a LineItem.Price()
method that uses the logic to get at the "real" (aka calculated) value. If I make the Price
property private now sqlx/JSON can't put the price in the existing LineItem.price
field. I saw a stackoverflow post where the two choices were use a method name like GetPrice()
and leave the struct property public (LineItem.Price
) meaning the API consumer would need to know not to use Price
property and use GetPrice()
method instead.
The other option being create a separate struct for exported data that gets used for DB & JSON (e.g. ExportedLineItems
) and a separate struct for the "API" (e.g. LineItems.price
and LineItems.Price()
). Even seeing an example I'm unclear how this would work in this case. I tried pulling the data with ExportedLineItems
and then converting it lineItem := models.LineItem(ExportedLineItem)
but it gives me:
cannot convert ExportedLineItem (variable of type models.ExportedLineItem) to type models.LineItem
Leaving the property public and using GetPrice()
seems like a simple solution but also seems like it goes against proper design by allowing the visibility to be public and the API is less clear (e.g. you have to know not to use LineItems.Price
directly). Can anyone provide insight?
Edit:
It's not my favorite but one approach I just tried that does seem to work is pulling the data using ExportedLineItem
and then manually assigning all properties and using setters for private ones.
lineItem := models.LineItem{
ID: ExportedLineItem.ID,
OrderID: ExportedLineItem.ID,
}
lineItem.SetPrice(ExportedLineItem.Price)
Price
public, and aLineItem.CalculatedPrice()
to return the calculated priceLineItem.Price
directly is both possible and wrong so I was thinking I could use package visibility to make it such that the correct choice was the obvious / only one.