[2.0] JSON library (parsing)

99 views
Skip to first unread message

Tymon Tobolski

unread,
May 18, 2012, 9:06:34 AM5/18/12
to play-fr...@googlegroups.com
Hi,

Play's JSON library provides typeclass-based Reads/Writes API (which is nice) but imho it's pretty useless. 
There are basically two functions for parsing "as" and "asOpt"

someJsValue.as[String]  ==> String or exception
someJsValue.asOpt[String] ==> Option[String]  cool

but...

Consider this simple example

case class Foo(a: String, b: Int)

implicit def FooReads: Reads[Foo] = new Reads[Foo]{
  def reads(json: JsValue): Foo = {
    for { 
     a <-  (json \ "a").asOpt[String] // secure parsing
     b <- (json \ "b").asOpt[Int] // also secure
   } yield Foo(a,b) /
  }
}

To above code will not compile, since return type of "reads" is Foo, not Option[Foo]. It has to be written like

implicit def FooReads: Reads[Foo] = new Reads[Foo]{
  def reads(json: JsValue): Foo = Foo(
    (json \ "a").as[String], // Hello exceptions!
    (json \ "b").as[Int]    // Exception again
  )
}


"asOpt" solves nothing. 

Why reads is not JsValue => Option[T] ? (Or even some Validation)

Julien Richard-Foy

unread,
May 18, 2012, 9:12:40 AM5/18/12
to play-fr...@googlegroups.com
> implicit def FooReads: Reads[Foo] = new Reads[Foo]{
>   def reads(json: JsValue): Foo = Foo(
>     (json \ "a").as[String], // Hello exceptions!
>     (json \ "b").as[Int]    // Exception again
>   )
> }

With this implementation, using asOpt[Foo] should return None if there
was an exception, otherwise Some[Foo].

sas

unread,
May 18, 2012, 5:09:52 PM5/18/12
to play-framework
Or you could check, if value is None raise an exception, otherwise
return the value

nut you would be missing the whole point of using an Option in the
first place, I guess...

Sadache Aldrobi

unread,
May 18, 2012, 5:21:46 PM5/18/12
to play-fr...@googlegroups.com
On Fri, May 18, 2012 at 3:06 PM, Tymon Tobolski <i...@teamon.eu> wrote:
Hi,

Play's JSON library provides typeclass-based Reads/Writes API (which is nice) but imho it's pretty useless. 

Don't you think "useless" is a bit offensive?
 
There are basically two functions for parsing "as" and "asOpt"

someJsValue.as[String]  ==> String or exception
someJsValue.asOpt[String] ==> Option[String]  cool

but...

Consider this simple example

case class Foo(a: String, b: Int)

implicit def FooReads: Reads[Foo] = new Reads[Foo]{
  def reads(json: JsValue): Foo = {
    for { 
     a <-  (json \ "a").asOpt[String] // secure parsing
     b <- (json \ "b").asOpt[Int] // also secure
   } yield Foo(a,b) /
  }
}

To above code will not compile, since return type of "reads" is Foo, not Option[Foo]. It has to be written like

implicit def FooReads: Reads[Foo] = new Reads[Foo]{
  def reads(json: JsValue): Foo = Foo(
    (json \ "a").as[String], // Hello exceptions!
    (json \ "b").as[Int]    // Exception again
  )
}


"asOpt" solves nothing. 

Why reads is not JsValue => Option[T] ? (Or even some Validation)


Besides Julien's answer, we are continually improving the Json library and I am sure it will result in one of the best Json api out there. 

--
You received this message because you are subscribed to the Google Groups "play-framework" group.
To view this discussion on the web visit https://groups.google.com/d/msg/play-framework/-/kg8klDREojwJ.
To post to this group, send email to play-fr...@googlegroups.com.
To unsubscribe from this group, send email to play-framewor...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/play-framework?hl=en.



--
www.sadekdrobi.com
ʎdoɹʇuǝ

Julien Richard-Foy

unread,
May 18, 2012, 5:55:13 PM5/18/12
to play-fr...@googlegroups.com
> Or you could check, if value is None raise an exception, otherwise
> return the value

According to its definition [1] it should work with provided
deserializers [2]. I think it’s a bug if it’s not working in your
case. Could you report it (or even fix it) in the tracker?
Thanks,
Julien

[1] https://github.com/playframework/Play20/blob/master/framework/src/play/src/main/scala/play/api/libs/json/JsValue.scala#L48
[2] https://github.com/playframework/Play20/blob/master/framework/src/play/src/main/scala/play/api/libs/json/Reads.scala
Reply all
Reply to author
Forward
0 new messages