Haskell Language
Data.Aeson - JSON en Haskell
Buscar..
Codificación y decodificación inteligentes usando genéricos
La forma más fácil y rápida de codificar un tipo de datos Haskell a JSON con Aeson es mediante el uso de genéricos.
{-# LANGUAGE DeriveGeneric #-}
import GHC.Generics
import Data.Text
import Data.Aeson
import Data.ByteString.Lazy
Primero creamos un tipo de datos Persona:
data Person = Person { firstName :: Text
, lastName :: Text
, age :: Int
} deriving (Show, Generic)
Para utilizar la función de encode
y decode
del paquete Data.Aeson
, necesitamos que Person
una instancia de ToJSON
y FromJSON
. Dado que derivamos Generic
for Person
, podemos crear instancias vacías para estas clases. Las definiciones predeterminadas de los métodos se definen en términos de los métodos proporcionados por la clase de tipo Generic
.
instance ToJSON Person
instance FromJSON Person
¡Hecho! Para mejorar la velocidad de codificación podemos cambiar ligeramente la instancia de ToJSON
:
instance ToJSON Person where
toEncoding = genericToEncoding defaultOptions
Ahora podemos usar la función de encode
para convertir Person
a un Bytestring (perezoso):
encodeNewPerson :: Text -> Text -> Int -> ByteString
encodeNewPerson first last age = encode $ Person first last age
Y para decodificar solo podemos usar decode
:
> encodeNewPerson "Hans" "Wurst" 30
"{\"lastName\":\"Wurst\",\"age\":30,\"firstName\":\"Hans\"}"
> decode $ encodeNewPerson "Hans" "Wurst" 30
Just (Person {firstName = "Hans", lastName = "Wurst", age = 30})
Una forma rápida de generar 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
Campos opcionales
A veces, queremos que algunos campos de la cadena JSON sean opcionales. Por ejemplo,
data Person = Person { firstName :: Text
, lastName :: Text
, age :: Maybe Int
}
Esto se puede lograr por
import Data.Aeson.TH
$(deriveJSON defaultOptions{omitNothingFields = True} ''Person)