We can solve this using TemplateHaskell
. Instead of writing ToJSON
and FromJON
we can use a specific key mapping.
First of all, we must build a name for a field that is not a type, for example:
data Owner = Owner {
id :: Int,
gravatar_id :: Text,
login :: Text,
avatar_url :: Text,
events_url :: URL,
followers_url :: URL,
following_url :: URL,
gists_url :: URL,
html_url :: URL,
organizations_url :: URL,
received_events_url :: URL,
repos_url :: URL,
starred_url :: URL,
subscriptions_url :: URL,
url :: URL,
owner_type :: Text,
site_admin :: Bool
} deriving (Generic, Show)
deriveJSON :: Options -> Name -> Q [Dec]
, fromJSON
ToJSON
.
Options
: fieldLabelModifier :: String -> String
, JSON. , , .
, ownerFieldRename :: String -> String
:
ownerFieldRename :: String -> String
ownerFieldRename "owner_type" = "type"
ownerFieldRename name = name
, , "owner_type"
, "type"
.
, deriveJSON
, :
$(deriveJSON defaultOptions {fieldLabelModifier = ownerFieldRename} ''Owner)
:
RenameUtils.hs
module RenameUtils where
ownerFieldRename :: String -> String
ownerFieldRename "owner_type" = "type"
ownerFieldRename name = name
MainFile.hs
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE DeriveGeneric #-}
import Data.Aeson.TH(deriveJSON, defaultOptions, Options(fieldLabelModifier))
import RenameUtils(ownerFieldRename)
import Data.Text (Text)
type URL = Text
data Owner = Owner {
id :: Int,
gravatar_id :: Text,
login :: Text,
avatar_url :: Text,
events_url :: URL,
followers_url :: URL,
following_url :: URL,
gists_url :: URL,
html_url :: URL,
organizations_url :: URL,
received_events_url :: URL,
repos_url :: URL,
starred_url :: URL,
subscriptions_url :: URL,
url :: URL,
owner_type :: Text,
site_admin :: Bool
} deriving (Show)
$(deriveJSON defaultOptions {fieldLabelModifier = ownerFieldRename} ''Owner)
JSON type
:
Prelude Main Data.Aeson> encode (Owner 1 "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" True)
"{\"id\":1,\"gravatar_id\":\"\",\"login\":\"\",\"avatar_url\":\"\",\"events_url\":\"\",\"followers_url\":\"\",\"following_url\":\"\",\"gists_url\":\"\",\"html_url\":\"\",\"organizations_url\":\"\",\"received_events_url\":\"\",\"repos_url\":\"\",\"starred_url\":\"\",\"subscriptions_url\":\"\",\"url\":\"\",\"type\":\"\",\"site_admin\":true}"
fieldLabelModifier
( ), -:
MainFile.hs
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE DeriveGeneric #-}
import Data.Aeson.TH(deriveJSON, defaultOptions, Options(fieldLabelModifier))
import Data.Text (Text)
type URL = Text
data Owner = Owner {
id :: Int,
gravatar_id :: Text,
login :: Text,
avatar_url :: Text,
events_url :: URL,
followers_url :: URL,
following_url :: URL,
gists_url :: URL,
html_url :: URL,
organizations_url :: URL,
received_events_url :: URL,
repos_url :: URL,
starred_url :: URL,
subscriptions_url :: URL,
url :: URL,
owner_type :: Text,
site_admin :: Bool
} deriving (Show)
$(deriveJSON defaultOptions {fieldLabelModifier = \x -> if x == "owner_type" then "type" else x} ''Owner)