-1

I am new to Scala. I was trying to parse an API response in Scala. The API response is in the format:

{"items":[{"name":"john", "time":"2017-05-11T13:51:34.037232", "topic":"india", "reviewer":{"id":"12345","name":"jack"}}, 
          {"name":"Mary", "time":"2017-05-11T13:20:26.001496", "topic":"math", "reviewer":{"id":"5678","name":"Tom"}}]}

My target is to populate a list of reviewer id's from the JSON response. I tried to create a JSON object from the response by

val jsonObject= parse(jsonResponse.getContentString()).getOrElse(Json.empty)

but couldn't get the reviewer ids from the json object. Even tried to iterate the JSON object, but didn't work.

halfer
  • 19,824
  • 17
  • 99
  • 186
das
  • 669
  • 2
  • 12
  • 22

2 Answers2

1

I am not familiar with circe but here is how you would do it with spray-json

import spray.json._
import DefaultJsonProtocol._

val jsonResponse = """{"items":[{"name":"john", "time":"2017-05-11T13:51:34.037232", "topic":"india", "reviewer":{"id":"12345","name":"jack"}},{"name":"Mary", "time":"2017-05-11T13:20:26.001496", "topic":"math", "reviewer":{"id":"5678","name":"Tom"}}]}"""

Need to define the schema using case classes:

case class Reviewer(id: String, name: String)
case class Item(name: String, time: String, topic: String, reviewer: Reviewer)
case class Items(items: Array[Item])

And their implicit conversion:

implicit val reviewerImp: RootJsonFormat[Reviewer] = jsonFormat2(Reviewer)
implicit val itemConverted: RootJsonFormat[Item] = jsonFormat4(Item)
implicit val itemsConverted: RootJsonFormat[Items] = jsonFormat1(Items)

Then it's very simple, parsing is just this:

val obj = jsonResponse.parseJson.convertTo[Items]

At last, get the ids for the reviewers:

val reviewers = obj.items.map(it => it.reviewer.id)
jamborta
  • 5,130
  • 6
  • 35
  • 55
  • It gives me error at the import statements itself, like- "Cannot resolve symbol spray" and "cannot resolve symbol DefaultJsonProtocol". Do I need to add some dependencies? Any clue? – das May 14 '17 at 11:54
  • 1
    Yes, you need `libraryDependencies += "io.spray" %% "spray-json" % "1.3.3"` – jamborta May 14 '17 at 12:08
0

You mentioned play, so here's how you could do it in Play

case class Reviewer(id:Long, name:String)
object Reviewer { implicit val format = Json.format[Reviewer] }

Once you have those set up you could either

val json:JsValue = Json.toJson(reviewerObject)
val json:JsObject = Json.toJson(reviewerObject).as[JsObject]
val json:String = Json.toJson(reviewerObject).toString // Valid json string

Or

val reviewer:Reviewer = Json.parse(reviewerJsonString).as[Reviewer]
val validates:Boolean = Json.parse(reviewerJsonString).validates[Reviewer]
Shai James
  • 56
  • 1
  • 6
  • object Reviewer { implicit val format = Json.format[Reviewer] } gives error - cannot resolve symbol 'format'. Json is circe Json ? – das May 14 '17 at 12:23
  • This would actually be for play.api.json. As far as I can tell from their documentation it doesn't look like circe supports implicit marshalling from json to class ( only the reverse ), your best bet to get it into a class would be `val foo:Foo = decode[Foo](fooCompatibleJson)`. In reverse you would be able to do `foo.asJson` – Shai James May 14 '17 at 13:15