Yesod contains Entity data type, i.e. model with its id from database. Yesod also makes Entity an instance of Aeson's ToJSON class, so it could be easily serialized as json. What is more awesome, Entity could be wrapped in any structure and it will be serialized as well. There are many types supporting ToJSON protocol. It is very handy and I like it a lot.
Unfortunately, serialization format Yesod provides for an Entity doesn't fit my needs, I'm looking for an easy and transparent way to change it.
Here is an example. I have simple model
data Company = Company
{ companyName :: Text
}
And corresponding Entity would be
Entity CompanyId Company
Now, code to fetch entities from database and return it as json looks like
getCompanyR = do
-- fetch companies from database
-- `companies` contains list of `Entity CompanyId Company`
companies <- runDB $ selectList ([] :: [Filter Company]) []
-- return it as json
-- List is also an instance of `ToJSON` so it could be serialized too
return . toJSON $ companies
Serialized list looks like
[{"key":"o52553881f14995dade000000","value":{"name":"Pizza World"}}]
And I would like it to be
[{"id":"o52553881f14995dade000000","name":"Pizza World"}]
I can see several options on how to change it each with its drawbacks:
Make a function to serialize
Entityaccording to my format, but then it will be impossible to serializeListofEntityies. I will end writing multiple functions to serializeEntityinside any structure it happens to be part of.Make a newtype for an
Entity, but then I should convert allEntityies toMyNewEntityies prior to serializing. It seems ugly to me, it will result in unnecessary conversion noise.
To summarize, my problem is that I can't change Entity ToJSON implementation, and I can't make Yesod to return something different than Entity. I'm forced to make a conversion, but what is a most transparent way to do it?