Проблемы с использованием персистентского getJust с entityIdToJSON
Я новичок в Haskell и пытаюсь написать веб-API Scotty с Persistent в качестве ORM. У меня проблемы со следующим кодом:
share [mkPersist sqlSettings, mkMigrate "migrateAll"] [persistLowerCase|
Account json
name String
description T.Text
deriving Show
...
|]
resource :: (PersistEntity a, PersistEntityBackend a ~ SqlBackend, ToJSON a, ToJSON (Entity a), FromJSON a) => String -> (Key a -> Key a) -> [SelectOpt a] -> Pool Connection -> S.ScottyM ()
resource url keyConv selectOpts pool = do
S.get (S.capture $ pluralize url) $ do
objects <- runDb pool $ selectList [] selectOpts
S.json $ map entityIdToJSON objects
S.get (S.capture $ url ++ "/:id") $ do
idParam <- S.param "id"
found <- runDb pool . getJust . keyConv . key $ idParam
S.json $ found
...
main :: IO ()
main = withSqlitePool "bla.db" 2 $ \pool -> do
S.scotty 3000 $ do
resource "/account" accountKey [Asc AccountId] pool
...
resource
Функция определяет веб-маршруты Скотти для объектов постоянных моделей, которые я хочу показать.
Первый маршрут определяется resource
извлекает всю коллекцию Например HTTP GET
в /accounts
возвращает все аккаунты.
Второй маршрут определяется resource
извлекает конкретную сущность по id Например HTTP GET
в /account/1
возвращает аккаунт с идентификатором 1.
Функции работают так, как они есть, но мне не нравится, что в сериализации json по умолчанию отсутствует идентификатор, поэтому я и использовал entityIdToJSON
в получить весь маршрут.
Тем не менее, при попытке включить entityIdToJSON
в маршруте get by id, на линии с S.json $ found
Я получаю следующую ошибку типа:
Main.hs:61:31-35: Could not deduce (a ~ Entity e0) …
from the context (PersistEntity a,
PersistEntityBackend a ~ SqlBackend,
ToJSON a,
ToJSON (Entity a),
FromJSON a)
bound by the type signature for
resource :: (PersistEntity a, PersistEntityBackend a ~ SqlBackend,
ToJSON a, ToJSON (Entity a), FromJSON a) =>
String
-> (Key a -> Key a)
-> [SelectOpt a]
-> Pool Connection
-> S.ScottyM ()
at /home/poida/src/moneymoney-api-scotty/Main.hs:48:13-189
`a' is a rigid type variable bound by
the type signature for
resource :: (PersistEntity a, PersistEntityBackend a ~ SqlBackend,
ToJSON a, ToJSON (Entity a), FromJSON a) =>
String
-> (Key a -> Key a)
-> [SelectOpt a]
-> Pool Connection
-> S.ScottyM ()
at /home/poida/src/moneymoney-api-scotty/Main.hs:48:13
In the second argument of `($)', namely `found'
In the second argument of `($)', namely `entityIdToJSON $ found'
In a stmt of a 'do' block: S.json $ entityIdToJSON $ found
Compilation failed.
Я попытался добавить ограничение типа Entity a
на ресурс, который сделал вещи хуже. Я также попытался покопаться в документации по взлому, но я не совсем понимаю все, что читаю. Документы, кажется, указывают, что Ключ - это Сущность вместе с его ключом.
tl; dr - Моя проблема заключается в попытке использовать результат функции getJust в Persistent, Key, с функцией entityIdToJSON в Persistent, которая ожидает Entity.
Есть идеи?
1 ответ
Я думаю, что вам нужно объединить свой ключ с found
производить Entity
,
Сохраните ключ, который вы передаете getJust
(разорвать линию, чтобы сохранить keyConv . key $ idParam
в let
), то сделайте Entity
от сохраненного ключа и found
,
Что-то вроде (не проверено):
S.get (S.capture $ url ++ "/:id") $ do
idParam <- S.param "id"
let k = keyConv . key $ idParam
found <- runDb pool . getJust $ k
S.json $ Entity k found