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)


Modified text is an extract of the original Stack Overflow Documentation
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow