Как создать "ActionCtxT" в Споке?
Я хочу извлечь значение из объекта JSON. И у меня есть это:
post "/test" $ do
a <- jsonBody'
let b = show (a :: Object) -- works well
myVal <- (a :: Object) .: "some_key" -- error
text "test123"
И ошибка:
• Couldn't match type ‘aeson-1.0.2.1:Data.Aeson.Types.Internal.Parser’
with ‘ActionCtxT () (WebStateM () MySession MyAppState)’
Expected type: ActionCtxT () (WebStateM () MySession MyAppState) a0
Actual type: aeson-1.0.2.1:Data.Aeson.Types.Internal.Parser a0
• In a stmt of a 'do' block:
myVal <- (a :: Aeson.Object) Aeson..: "some_key"
Я знаю, что это значит: строка с myVal должна возвращать что-то типа ActionCtxT, а также все другие строки. Или чистая ценность. Таким образом, как это исправить?
1 ответ
jsonBody' :: (MonadIO m, FromJSON a) => ActionCtxT ctx m a
jsonBody'
дает вам возможность проанализировать тело запроса с помощью Aeson FromJSON
пример.
Обычно проще использовать Aeson, сопоставив данные JSON с пользовательским типом данных, а затем предоставив FromJSON
экземпляр для этого типа данных.
Перефразируя пример, который вы можете найти в документации Aeson, если ваш JSON выглядит так:
{ "name": "Joe", "age": 12 }
Затем вы можете создать тип данных:
data Person = Person {
name :: Text
, age :: Int
} deriving Show
и вручную создайте экземпляр FromJSON:
{-# LANGUAGE OverloadedStrings #-}
instance FromJSON Person where
parseJSON (Object v) = Person <$>
v .: "name" <*>
v .: "age"
-- A non-Object value is of the wrong type, so fail.
parseJSON _ = empty
Вы также можете автоматически получить экземпляр FromJSON из вашего типа данных.