Haskell Language
Data.Aeson - JSON dans Haskell
Recherche…
Encodage et décodage intelligents à l'aide de génériques
Le moyen le plus simple et le plus rapide d'encoder un type de données Haskell en JSON avec Aeson consiste à utiliser des génériques.
{-# LANGUAGE DeriveGeneric #-}
import GHC.Generics
import Data.Text
import Data.Aeson
import Data.ByteString.Lazy
Commençons par créer un type de données Personne:
data Person = Person { firstName :: Text
, lastName :: Text
, age :: Int
} deriving (Show, Generic)
Pour utiliser la fonction d' encode
et de decode
du package Data.Aeson
, nous devons Data.Aeson
Person
comme instance de ToJSON
et FromJSON
. Puisque nous dérivons Generic
for Person
, nous pouvons créer des instances vides pour ces classes. Les définitions par défaut des méthodes sont définies en fonction des méthodes fournies par la classe de type Generic
.
instance ToJSON Person
instance FromJSON Person
Terminé! Afin d'améliorer la vitesse d'encodage, nous pouvons modifier légèrement l'instance ToJSON
:
instance ToJSON Person where
toEncoding = genericToEncoding defaultOptions
Maintenant, nous pouvons utiliser la fonction encode
pour convertir Person
en un bytestring (paresseux):
encodeNewPerson :: Text -> Text -> Int -> ByteString
encodeNewPerson first last age = encode $ Person first last age
Et pour décoder, nous pouvons simplement utiliser le decode
:
> encodeNewPerson "Hans" "Wurst" 30
"{\"lastName\":\"Wurst\",\"age\":30,\"firstName\":\"Hans\"}"
> decode $ encodeNewPerson "Hans" "Wurst" 30
Just (Person {firstName = "Hans", lastName = "Wurst", age = 30})
Un moyen rapide de générer un Data.Aeson.Value
{-# LANGUAGE OverloadedStrings #-}
module Main where
import Data.Aeson
main :: IO ()
main = do
let example = Data.Aeson.object [ "key" .= (5 :: Integer), "somethingElse" .= (2 :: Integer) ] :: Value
print . encode $ example
Champs facultatifs
Parfois, nous voulons que certains champs de la chaîne JSON soient facultatifs. Par exemple,
data Person = Person { firstName :: Text
, lastName :: Text
, age :: Maybe Int
}
Cela peut être réalisé par
import Data.Aeson.TH
$(deriveJSON defaultOptions{omitNothingFields = True} ''Person)