How to enforce strict serialization of JSON in Play 2.x

前端 未结 2 807
臣服心动
臣服心动 2020-12-20 23:11

Play\'s JSON serialization is by default permissive when serializing from JSON into a case class. For example.

case class Stuff(name: String, value: Option[         


        
相关标签:
2条回答
  • 2020-12-20 23:19

    Inspired from Travis' comment to use LabelledGeneric I was able achieve compile time safe solution.

    object toStringName extends Poly1 {
        implicit def keyToStrName[A] = at[Symbol with A](_.name)
    }
    case class Foo(bar: String, boo: Boolean)
    
    val labl = LabelledGeneric[Foo]
    val keys = Keys[labl.Repr].apply
    

    now keys.map (toStringName).toList will give you

    res0: List[String] = List(bar, boo)

    0 讨论(0)
  • 2020-12-20 23:29

    You can verify that the object doesn't contain extra keys before performing your own decoding:

    import play.api.data.validation.ValidationError
    
    def onlyFields(allowed: String*): Reads[JsObject] = Reads.filter(
      ValidationError("One or more extra fields!")
    )(_.keys.forall(allowed.contains))
    

    Or if you don't care about error messages (and that one's not very helpful, anyway):

    def onlyFields(allowed: String*): Reads[JsObject] =
      Reads.verifying(_.keys.forall(allowed.contains))
    

    And then:

    implicit val stuffReads: Reads[Stuff] = onlyFields("name", "value") andThen (
      (__ \ 'name).read[String] and
      (__ \ 'value).readNullable[Boolean]
    )(Stuff)
    

    The repetition isn't very nice, but it works.

    0 讨论(0)
提交回复
热议问题