how to retrieve and inject sections from and to JSON

136 Views Asked by At

If I have an incoming JSON of following structure

[
   {
      "personId" : 12,
      "name": "John Doe",
      "age": 48,
      "birthdate": "12/1/1954",
      "relationships": [
           {
              "relationType":"parentOf",
              "value" : "Johnny walker"
          },
          {
             "relationType":"sonOf",
             "value" : "Charles Smith"
         }
      ]
   },
   {
        "personId" : 13,
       "name": "Merry Christmas",
       "age": 28,
       "birthdate": "12/1/1985",
       "relationships": [
            {
              "relationType":"sisteOf",
             "value" : "Will Smith"
           },
           {
             "relationType":"cousinOf",
             "value" : "Brad Pitt"
          }
       ]
   }
]

And requirement is that for each Person record controller will have to carve out relationships array and store each record from it in a separate relationship table with personId association while persisting this incoming JSON.

And subsequently when querying these persons records system will have to lookup relationships for each person from relationships table and inject them to form the same above looking JSON to give back to UI for rendering.

What's the best efficient way to perform this "carve out" and later "inject" operations using Play framework in Scala? (using Slick in persistent layer APIs) I have looked at this JSON transformation link and json.pickBranch in there but not quite sure if that'll be fully applicable here for "carve out" and "inject" use cases for preparing JSON shown in the example. are there any elegant ideas?

1

There are 1 best solutions below

0
On

One way, which is pretty straightforward, is to use case classes along with Play Json inceptions

import play.api.libs.json.Json

case class Relationship(relationType: String, value: String)

object Relationship {

  implicit val RelationshipFormatter = Json.format[Relationship]

}

case class Person(personId: String, name: String, age: Int, birthdate: String, relationships: Seq[Relationship]) {

  def withRelationships(relationship: Seq[Relationship]) = copy(relationships = relationships ++ relationship)

}

object Person {

  implicit val PersonFormatter = Json.format[Person]

}

Now you can convert a json value to Person by using the following code, provided that jsValue is a json value of type JsValue (which in play controllers you can get by request.body.asJson):

Json.fromJson[Person](jsValue)

In Play controllers, you can

For converting a Person to json you can use the following code provided that person is a value of type Person in your context:

Json.toJson(person)

The only remaining thing is your Slick schemas which is pretty straight forward.

One option is to use a simple schema for Person, without relations and one schema for Relation with a foreign key to Person table. Then you need to find all relations associated with a specific Person, namely person and then append them to that person by calling the withRelationships method which gives you a new Person which you can serve as json:

val person = ....      // find person
val relations = ....   // find relationships associated with this person
val json = Json.toJson(person.withRelationships(relations))