处理 Yesod 中的 JSON 个帖子

Handling JSON posts in Yesod

AngularJS 客户端正在向 Yesod 服务器发送 JSON post 以更新个人记录。 post 可以包含以下字段,每个字段都是可选的 - 客户端可以发送这些字段的任何子集:

为了稍微限制讨论,让我们假设客户端此刻只想切换 activity,因此它只会发送活动值(它特别希望保持其余部分不变)和消息将是:

{
  active: 0
}

现在在服务器上,我们从URL(例如/api/v1.0/person/1)知道了这个人的id,但是客户端没有发送一个完整的人实体,所以通常:

person <- requireJsonBody :: Handler Person
_ <- runDB $ update personId ...

在这里不起作用。似乎需要一种更灵活的方法。也许是这样的:

mapToUpdate :: PersonInfo -> [Update PersonInfo]

其中 PersonInfo 是 FromJSON 的实例,定义为与 Person 匹配,但具有 Maybe a 类型的所有字段。然而,这似乎与 DRY 完全相反。

总结一下:如何处理 Yesod 中的这种用例并再次假设客户端可以发送一个人字段的任何子集?

你可以想象更可怕的场景。例如,一个 JSON post 需要映射到多个数据库实体的更新(api 实体不必映射 1:1 到数据库实体)。

我从来没有尝试过这个,但这是一个理论上的方法:

  1. 从数据库中抓取当前值
  2. 通过调用 toJSON
  3. 将该值序列化为 aeson Value
  4. 编写某种 "update" 算法,将两个 Value 合并在一起,例如mergeValues :: Value -> Value -> Value
  5. 将原始实体与用户上传的值合并
  6. 尝试用parseJSON
  7. 解析结果值
  8. 如果成功,使用replace将其放回数据库