Yesod содержит Entity
тип данных, то есть модель с ее идентификатором из базы данных. Yesod также делает Entity
экземпляром класса Aeson ToJSON
, поэтому его можно легко сериализовать как json. Что более удивительно, Entity
может быть обернуто в любую структуру, и оно также будет сериализовано. Существует много типов, поддерживающих протокол ToJSON
. Это очень удобно, и мне это очень нравится.Переопределение поведения экземпляра
К сожалению, формат сериализации Yesod обеспечивает для Entity
не соответствует моим потребностям, я ищу простой и прозрачный способ его изменения.
Вот пример. У меня есть простая модель
data Company = Company
{ companyName :: Text
}
И соответствующая Entity будет
Entity CompanyId Company
Теперь код для извлечения объектов из базы данных и возвращает его как JSON выглядит
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 список выглядит
[{"key":"o52553881f14995dade000000","value":{"name":"Pizza World"}}]
И я хотел бы, чтобы это было
[{"id":"o52553881f14995dade000000","name":"Pizza World"}]
Я вижу несколько вариантов, как изменить его каждый со своими недостатками:
Сделать функцию упорядочивания
Entity
по моему формату, но потом будет невозможно сериализоватьList
изEntity
. Я закончу писать несколько функций для сериализацииEntity
внутри любой структуры, частью которой она является.Сделать NewType для
Entity
, но тогда я должен преобразовать всеEntity
х годов прошлого века вMyNewEntity
х до сериализации. Мне кажется уродливым, это приведет к ненужному шуму преобразования.
Итак, моя проблема заключается в том, что я не могу изменить Entity
ToJSON
реализации, и я не могу сделать Йесод, чтобы вернуть что-то иное, чем Entity
. Я вынужден сделать конверсию, но что является самым прозрачным способом сделать это?
Это, безусловно, способ пойти, если вам нужно несколько представлений. Это не совсем проблема, потому что мне нужно только одно пользовательское представление. Я придумал более легкое решение, но ваш более общий. Спасибо. – lambdas