我需要解析没有严格结构的json API响应:
{
response: { /* any object here */ }
}
Run Code Online (Sandbox Code Playgroud)
如何编写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
Run Code Online (Sandbox Code Playgroud)
我喜欢将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"
Run Code Online (Sandbox Code Playgroud)
要在没有解析的情况下执行映射,要将a转换Value为a FromJSON a => a,请使用parse/ parseEither/ parseMaybefamily并运行由其生成的解析器parseJSON
mapValue :: FromJSON a => Value -> Either String a
mapValue = parseString parseJSON
Run Code Online (Sandbox Code Playgroud)