Aeson解析动态对象

And*_*sov 2 haskell aeson

我需要解析没有严格结构的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)

J. *_*son 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"
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)