我是 Haskell 的新手,正在尝试编写一个使用 Persistent 作为 ORM 的 Scotty Web API。我在使用以下代码时遇到问题:
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
函数为我想要公开的持久模型对象定义了 Scotty Web 路由。
定义的第一个路由resource
检索整个集合。例如HTTP GET
返回/accounts
所有帐户。
定义的第二条路由resource
通过 id 检索特定实体。例如 aHTTP GET
返回/account/1
id 为 1 的帐户。
这些函数按原样工作,但我不喜欢默认的 json 序列化不包含 id,这就是我entityIdToJSON
在 get all 路由中使用的原因。
但是,当尝试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
到资源中,这让事情变得更糟。我还尝试在有关 hackage 的文档中进行挖掘,但我不太了解我正在阅读的所有内容。文档似乎表明密钥是实体及其密钥。
tl; dr - 我的问题是尝试使用 Persistent 的 getJust 函数的结果,一个 Key 和 Persistent 的 entityIdToJSON 函数,该函数需要一个实体。
有任何想法吗?