我需要解析没有严格结构的json API响应:
{
response: { /* any object here */ }
}
如何编写parseResponse
能够解析(或选择Parser)以供以后使用?
我的最后一次尝试如下。我不喜欢它,因为它不允许像Aeson decode
那样选择响应类型。
data APIResponse =
APIResponse { response :: Value } deriving (Show,Generic)
instance FromJSON APIResponse
parseResponse :: BC.ByteString -> Either String Value
parseResponse resp =
case eitherDecode . BLC.fromStrict $ resp of
Right x -> Right $ response x
Left msg -> Left msg
答案 0 :(得分:7)
我喜欢将Aeson视为两个截然不同的步骤,即ByteString -> Value
的解析和FromJSON a => Value -> a
的映射。如果您不能立即知道正确的映射是什么,那么您可以简单地解析为Value
。稍后在运行时,当您决定正确的映射时,您可以稍后再这样做。
import qualified Data.HashMap.Strict as Hm
decodeResponse :: ByteString -> Either String Value
decodeResponse bs = do
val <- eitherDecode bs
case val of
Object o -> case Hm.lookup "response" o of
Nothing -> fail "Invalid structure, missing 'response' key"
Just resp -> return resp
_ -> fail "Invalid structure, expected an object"
要执行不带解析的映射,要将Value
转换为FromJSON a => a
,请使用parse
/ parseEither
/ parseMaybe
系列并运行由parseJSON
mapValue :: FromJSON a => Value -> Either String a
mapValue = parseString parseJSON