省略 Haskell 的 Aeson 中的 Nothing/null 字段
Omitting Nothing/null fields in Haskell's Aeson
我有一个类型
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE MultiWayIf #-}
import GHC.Generics
import Data.Aeson.TH
import Data.Aeson.Types
data MyJSONObject = MyJSONObject
{ name :: String
, ptype :: Maybe String
, pid :: Maybe String
, subject :: Maybe String
, message :: Maybe String
} deriving (Show, Generic)
还有更多 Maybe String
字段。我的FromJSON
和ToJSON
是由TemplateHaskell
函数
提供的
$(deriveJSON defaultOptions
{
omitNothingFields = True
, fieldLabelModifier = \f -> if
| f == "ptype" -> "type" -- reserved keyword
| f == "pid" -> "id" -- Prelude function name
| otherwise -> f
} ''MyJSONObject)
最终,该程序的输出是一个 JSON 文档,旨在供不允许某些字段具有空值的应用程序使用,即使它确实允许这些字段不存在。换句话说,subject
不出现在 JSON 文档中是完全没问题的,但如果它确实存在,它的值就不能为 null。我的期望是 omitNothingFields
会处理此要求,但情况似乎并非如此:decode
d JSON 仍然具有不存在的字段的 Nothing
值,并且 encode
d JSON 具有这些字段的 null
值。前一种情况很好;后一种情况不是,因此是问题。
我是否误用或误解了 omitNothingFields
的用途?如何忽略具有 Nothing
/null
值的字段?
适合我。尝试使用泛型派生而不是 TH。也许就是这样。
*Main Data.Aeson> decode "{\"name\":\"str\"}" :: Maybe MyJSONObject
Just (MyJSONObject {name = "str", ptype = Nothing, pid = Nothing, subject = Nothing, message = Nothing})
*Main Data.Aeson> encode (MyJSONObject "str" Nothing Nothing Nothing Nothing)
"{\"name\":\"str\"}"
完整代码为
{-# LANGUAGE DeriveGeneric #-}
import GHC.Generics
import Data.Aeson
import Data.Aeson.Types
data MyJSONObject = MyJSONObject
{ name :: String
, ptype :: Maybe String
, pid :: Maybe String
, subject :: Maybe String
, message :: Maybe String
} deriving (Show, Generic)
instance ToJSON MyJSONObject where
toJSON = genericToJSON defaultOptions
{ omitNothingFields = True }
instance FromJSON MyJSONObject where
parseJSON = genericParseJSON defaultOptions
{ omitNothingFields = True }
使用 GHC 8.2.1,aeson-1.1.2.0
。
我有一个类型
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE MultiWayIf #-}
import GHC.Generics
import Data.Aeson.TH
import Data.Aeson.Types
data MyJSONObject = MyJSONObject
{ name :: String
, ptype :: Maybe String
, pid :: Maybe String
, subject :: Maybe String
, message :: Maybe String
} deriving (Show, Generic)
还有更多 Maybe String
字段。我的FromJSON
和ToJSON
是由TemplateHaskell
函数
$(deriveJSON defaultOptions
{
omitNothingFields = True
, fieldLabelModifier = \f -> if
| f == "ptype" -> "type" -- reserved keyword
| f == "pid" -> "id" -- Prelude function name
| otherwise -> f
} ''MyJSONObject)
最终,该程序的输出是一个 JSON 文档,旨在供不允许某些字段具有空值的应用程序使用,即使它确实允许这些字段不存在。换句话说,subject
不出现在 JSON 文档中是完全没问题的,但如果它确实存在,它的值就不能为 null。我的期望是 omitNothingFields
会处理此要求,但情况似乎并非如此:decode
d JSON 仍然具有不存在的字段的 Nothing
值,并且 encode
d JSON 具有这些字段的 null
值。前一种情况很好;后一种情况不是,因此是问题。
我是否误用或误解了 omitNothingFields
的用途?如何忽略具有 Nothing
/null
值的字段?
适合我。尝试使用泛型派生而不是 TH。也许就是这样。
*Main Data.Aeson> decode "{\"name\":\"str\"}" :: Maybe MyJSONObject
Just (MyJSONObject {name = "str", ptype = Nothing, pid = Nothing, subject = Nothing, message = Nothing})
*Main Data.Aeson> encode (MyJSONObject "str" Nothing Nothing Nothing Nothing)
"{\"name\":\"str\"}"
完整代码为
{-# LANGUAGE DeriveGeneric #-}
import GHC.Generics
import Data.Aeson
import Data.Aeson.Types
data MyJSONObject = MyJSONObject
{ name :: String
, ptype :: Maybe String
, pid :: Maybe String
, subject :: Maybe String
, message :: Maybe String
} deriving (Show, Generic)
instance ToJSON MyJSONObject where
toJSON = genericToJSON defaultOptions
{ omitNothingFields = True }
instance FromJSON MyJSONObject where
parseJSON = genericParseJSON defaultOptions
{ omitNothingFields = True }
使用 GHC 8.2.1,aeson-1.1.2.0
。