将记录的用户ID插入play.api.libs.json.Reads

时间:2014-05-11 18:41:51

标签: json scala playframework

我想处理创建新实体的请求,其定义如下:

Group (id, name, avatarLink, groupOwnerId)

groupOwnerId是当前登录用户的ID。

我已按以下方式编写了阅读对象

 implicit val groupReads: Reads[models.GroupDAL.Group] = (
 (JsPath \ "name").read[String] and
 (JsPath \ "avatarLink").readNullable[String]
 )(models.GroupDAL.Group.apply(0L,_,_,0L))

正确设置此变量的正确方法是什么。从现在开始我只提出了一个想法 - 在客户端的json中设置groupOwnerId值,并生成自定义验证器,验证给定变量是否真的是当前登录的用户(因为创建其所有者为不同用户的组是不正常的)。

但IMO这是一种严格的解决方案,我必须这样做,我想知道如果我在文档中省略了 - 也许有更简单的解决方案。

1 个答案:

答案 0 :(得分:0)

我想,当您尝试反序列化您的JSON值时,您可以在某处获得登录用户的ID。如果是这样,那么做什么:

 implicit def groupReads(implicit groupOwnerId: Long): Reads[models.GroupDAL.Group] = (
 (JsPath \ "name").read[String] and
 (JsPath \ "avatarLink").readNullable[String]
 )(models.GroupDAL.Group.apply(0L,_,_,groupOwnerId))

允许你写

 val group: Option[Group] = Json.parse(jsonString).asOpt[Group]

只要groupOwnerId在隐式范围内可用。但是,在这种情况下,您可能不希望Long使用groupOwnerId,因为这可能会导致含糊不清的隐含值。解决这个问题的方法是将其包装在一个值类中,例如:

 class UserId(val underlying: Long) extends AnyVal

并在Group类型的定义中使用该类型:

 class Group(id: UserId, name: String, avatarLink: Option[String], groupOwnerId: UserId)

当然,您必须将读者的签名更改为:

implicit def groupReads(implicit groupOwnerId: UserId): Reads[models.GroupDAL.Group]