FromJSON [Object] implementation

132 views Asked by At

I have a project where I need to parse JSON. I get a list of objects, but it's all contained inside the "data" key. Currently I have a little object to help me :

data StorageList = StorageList { sl :: [Storage] }

instance FromJSON StorageList where
  parseJSON = withObject "StorageList" $ \v -> StorageList
    <$> v .: "data"

Then I just use "sl" to get my actual list from the result.

It works perfectly fine, but I think we'll all agree that it's ugly. I imagine there must be an easier way to parse that [Storage] directly, somehow telling parseJSON to just start from inside data. Oh, and I'm using httpJSONEither from http-conduit, but if there is no way to do it with that I can change, I suppose.

EDIT : Here is storage :

data Storage = Storage { storageId     :: Text
                       , storageName   :: Text
                       , storageNode   :: Text
                       , storageSize   :: Int
                       , storageUsed   :: Int
                       } deriving Show

instance FromJSON Storage where
  parseJSON = withObject "Storage" $ \v -> Storage
    <$> v .: "id"
    <*> v .: "storage"
    <*> v .: "node"
    <*> v .: "maxdisk"
    <*> v .: "disk"

EDIT 2 : What I'm trying to parse has this look :

{
  "data":
  [
    {
      "id": "X",
      "storage": "X",
      ...
    },
    {
      "id": "Y",
      "storage": "Y",
      ...
    },
    ...
  ]
}

Hoping that'll be clearer. I'm using that ugly "StorageList" object to get rid of that data key wrapping everything, and it works, but I'm sure there must be a better way to handle it.

0

There are 0 answers