使用Playframework 2.4 Json变换器实现Google PATCH语义

时间:2016-02-29 17:49:44

标签: json playframework playframework-2.0 transform

我无法想出Patch语义的解决方案:

  1. 如果json没有属性,我需要跳过修改
  2. 如果json属性有null,我需要删除此属性(对于不需要的属性)
  3. 在其他情况下我需要设置值
  4. 我需要转换为mongo.db更新命令(“$ unset”代表2,“$ set”代表3)

    例如,我需要使用必需属性“摘要”存储json。所以:

    {"summary": "modified by patch", "description": null}
    

    必须转换为:

    {
      "$set" : {
        "summary": "modified by patch"
      },
      "$unset": {
        "description": ""
      }
    }
    

    这个json

    {"description": null}
    

    必须转换为(“摘要”被跳过):

    {
      "$unset" : {
        "description": ""
      }
    }
    

    并为此

    {"summary": null}
    

    我需要转换错误(无法删除必需的属性)

1 个答案:

答案 0 :(得分:1)

我的解决方案是

def patch(path: JsPath)(r: Reads[JsObject]) = Reads{json =>
  path.asSingleJsResult(json).fold(
    _ => JsSuccess(Json.obj()),
    _ => r.reads(json)
  )
}

和所有必需的属性

def requiredError = ValidationError("error.remove.required")

val summaryPatch = patch(__ \ "summary")(
  (__ \ "$set" \ "summary").json.copyFrom( 
    (__ \ "summary").json.pick.filterNot(requiredError)(_ == JsNull)
  )
)

其他

val descriptionPatch = patch(__ \ "description")(
  (__ \ "$set" \ "description").json.copyFrom(
    (__ \ "description").json.pick.filterNot(_ == JsNull) 
  ) orElse 
  (__ \ "$unset" \ "description").json.copyFrom( 
    (__ \ "description").json.pick) 
  )
)

mongo.db trasformer:

toMongoPatch = (summaryPatch and descriptionPatch).reduce