Haskell의 Aeson 라이브러리를 활용한 JSON 처리

Data.Aeson 라이브러리

Aeson 라이브러리 설치

$ cabal install aeson
Installed aeson-1.4.7.1
Prelude> :m +Data.Aeson
Prelude Data.Aeson> 

Data.Aeson은 Haskell에서 JSON 데이터를 처리하기 위한 표준 라이브러리입니다.

AST(추상 구문 트리) 다루기

Prelude Data.Aeson> decode "{\"id\": 42}" :: Maybe Value
Just (Object (fromList [("id",Number 42.0)]))
Prelude Data.Aeson> decode "{\"tags\": [\"haskell\",\"json\"]}" :: Maybe Value
Just (Object (fromList [("tags",Array [String "haskell",String "json"])]))
Prelude Data.Aeson> decode "[10,20,30]" :: Maybe [Int]
Just [10,20,30]
Prelude Data.Aeson> "{\"x\":1,\"y\":2}" :: Maybe (Data.Map.Map String Int)
Just (fromList [("x",1),("y",2)])

User 모델 정의 및 처리 (1)

{-# LANGUAGE DeriveGeneric #-}

import GHC.Generics
import Data.Aeson
import Data.Text

data User = User {
      username :: Text
    , years    :: Int
    } deriving (Generic, Show)

data UserList = UserList {
      users :: [User]
    } deriving (Generic, Show)

instance ToJSON User
instance FromJSON User

instance ToJSON UserList
instance FromJSON UserList
*Main> :set -XOverloadedStrings
*Main> encode (User {username = "Alice", years = 25})
"{\"username\":\"Alice\",\"years\":25}"
*Main> decode "{\"username\":\"Alice\",\"years\":25}" :: Maybe User
Just (User {username = "Alice", years = 25})
*Main> encode (UserList {users = [User {username = "Alice", years = 25}]})
"{\"users\":[{\"username\":\"Alice\",\"years\":25}]}"
*Main> decode "{\"users\":[{\"username\":\"Alice\",\"years\":25}]}" :: Maybe UserList
Just (UserList {users = [User {username = "Alice", years = 25}]})
  • instance ToJSON UserList - UserList 타입의 객체를 JSON 문자열로 직렬화하려면 UserList 타입이 ToJSON 타입 클래스의 인스턴스여야 합니다.
  • instance FromJSON UserList - JSON 문자열을 UserList 타입의 객체로 역직렬화하려면 UserList 타입이 FromJSON 타입 클래스의 인스턴스여야 합니다.

User 모델 정의 및 처리 (2)

{-# LANGUAGE OverloadedStrings #-}

import Data.Aeson
import Data.Text

data User = User {
      username :: Text
    , years    :: Int
    } deriving Show

data UserList = UserList {
      users :: [User]
    } deriving Show

instance FromJSON User where
    parseJSON = withObject "User" $ \v -> User
        <$> v .: "username"
        <*> v .: "years"

instance ToJSON User where
    toJSON (User username years) =
        object ["username" .= username, "years" .= years]

instance FromJSON UserList where
    parseJSON = withObject "UserList" $ \v -> UserList
        <$> v .: "users"

instance ToJSON UserList where
    toJSON (UserList users) =
        object ["users" .= users]
*Main> :set -XOverloadedStrings
*Main> encode (User {username = "Bob", years = 30})
"{\"username\":\"Bob\",\"years\":30}"
*Main> decode "{\"username\":\"Bob\",\"years\":30}" :: Maybe User
Just (User {username = "Bob", years = 30})
*Main> encode (UserList {users = [User {username = "Bob", years = 30}]})
"{\"users\":[{\"username\":\"Bob\",\"years\":30}]}"
*Main> decode "{\"users\":[{\"username\":\"Bob\",\"years\":30}]}" :: Maybe UserList
Just (UserList {users = [User {username = "Bob", years = 30}]})

User 모델 정의 및 처리 (3)

{-# LANGUAGE OverloadedStrings #-}

import Data.Aeson
import Data.Text

data User = User {
      username :: Text
    , years    :: Int
    } deriving Show

instance FromJSON User where
    parseJSON = withObject "User" $ \v -> User
        <$> v .: "username"
        <*> v .:? "years" .!= 18
*Main> :set -XOverloadedStrings
*Main> decode "{\"username\":\"Charlie\"}" :: Maybe User
Just (User {username = "Charlie", years = 18})

User 모델 정의 및 처리 (4)

{-# LANGUAGE DeriveGeneric #-}

import GHC.Generics
import Data.Aeson
import Data.Text (Text)

data User = User {
      user_NAME :: Text
    , user_AGE  :: Int
    } deriving (Generic, Show)

customOptions = defaultOptions
                { fieldLabelModifier = drop $ length ("user_" :: String)
                }

instance ToJSON User where
    toJSON = genericToJSON customOptions
instance FromJSON User where
    parseJSON = genericParseJSON customOptions
*Main> :set -XOverloadedStrings
*Main> encode (User {user_NAME = "David", user_AGE = 35})
"{\"AGE\":35,\"NAME\":\"David\"}"
*Main> decode "{\"NAME\":\"David\",\"AGE\":35}" :: Maybe User
Just (User {user_NAME = "David", user_AGE = 35})

태그: Haskell Aeson JSON Data.Serialization

6월 26일 21:45에 게시됨