我有一台接收JSON的服务器,如下所示:
{ "foo": "bar", "bono": "bobo",
"result": { "some": ["complex", "JSON", "structure",...
}
其中所有内容都是服务器除了之外的“结果”,它将被转发到客户端(Worker --JSON - > Server - value of“result” - - >客户端)。因此,当用aeson解析这个东西时,我希望将“result”的值保持为字符串(或Text或whatnot),这样我就可以将它转发给客户端而不需要关心内部的内容。问题是“结果”可以是任何东西(数组,对象等)。 所以如果我这样做
data RPCResult = RPCResult { foo :: Text, result :: Text }
aeson的decode
函数将返回Nothing
,因为“result”不一定是JSON字符串......
我如何告诉aeson保留JSON对象的部分内容并将它们交给我,以便我可以用它们做我想做的事情?
答案 0 :(得分:3)
我似乎通过将result
的类型设为Data.Aeson.Value
来获得某种解决方案,然后在对传入的JSON执行decode
之后,我提取result
并在转发前运行encode
。我不确定这是否是最好的解决方案(因为我不是“将它保持为字符串”,如问题所述,但解码然后重新编码...)但它有效:
import Data.Aeson
import Data.Maybe
import Data.ByteString.Lazy (fromStrict, ByteString)
import Data.ByteString.UTF8 (fromString)
import Control.Applicative
data RPCResult = RPCResult { foo :: Text, result :: Value }
instance FromJSON RPCResult where
parseJSON (Object v) = RPCResult <$> v .: "foo" <*> v .: "result"
-- example just so you get the idea:
toRPCResult :: String -> RPCResult
toRPCResult = fromJust . decode . fromStrict . fromString
getResult :: String -> ByteString
getResult = encode . result . toRPCResult