在haskell中用aeson解析部分json对象
Posted
技术标签:
【中文标题】在haskell中用aeson解析部分json对象【英文标题】:Parsing partial json objects with aeson in haskell 【发布时间】:2013-03-04 19:50:48 【问题描述】:我正在 Haskell 中使用 Warp(可能还有 Scotty)和酸状态创建一个相当简单的 CRUD Web 服务。
在酸性状态下,我将用户记录存储在 Data.Map 中(根据 this 示例)。我知道这些记录在创建时总是完整的,所以我不需要用很多 MaybeS 来获得资格。但是,在更新用户时,客户端可能会选择发送部分 json 对象,其中仅填充一些字段。
表示这个的惯用方式是什么?我是否应该在所有可选键PartialUser前面有一个数据声明FullUser,没有MaybeS,而一个与MaybeS完全相同,并让aeson自动为后者派生编码和解码,最后编写我自己的类型更新函数:: FullUser -> PartialUser -> FullUser?
代码不会太多,但感觉有点难看,有点违反 DRY。它应该是 Web 服务器中如此常见的任务,所以也许它已经被通用解决了(可能使用 TH)?
我意识到我可以只存储 json 字符串并始终检查丢失的键,使其稍微笨拙但更适合未来的架构更改,但我仍然想知道我将如何在“类型安全”中做到这一点方式。
编辑: 或者也许我应该只有 FullUser 并使用 aeson-lens 从 FullUser 和 json 字符串编写一个简单的更新函数?
【问题讨论】:
【参考方案1】:惯用的 Haskell 尽可能多地进行静态检查。您应该始终从是否可以用静态检查替换动态检查的角度来处理您的问题。这基本上就是使以下关于 Haskell 的陈述非常接近现实的原因:“如果它编译,它就可以工作”。因此,使用纯 JSON 绝对是“不”。
您使用FullUser
和PartialUser
的解决方案是正确的。尽管我建议采用不同的命名方法:User
和 UserJSON
- 这样您就可以获得非常具有描述性和合理性的含义。
然而,Aeson 有一个小问题:生成的实例don't yet support parsing missing fields(请就这个问题投票)。所以你必须手动定义实例。
【讨论】:
感谢您的意见!是的,命名只是为了让问题更清楚。由于在这种情况下生成的实例是不够的,我想我会使用一个更新函数,它接受一个 FullUser 和一个 json 字符串并使用 aeson-lens(可能还有一个用于 FullUser 的镜头)来更新它。以上是关于在haskell中用aeson解析部分json对象的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Haskell 的“let”表达式中用“type”定义一个值?