summerNight summerNight - 1 year ago 58
Scala Question

Scala/Play - Building an aggregated JSON by getting partial data from the list

I have a following case class:

case class Vehicle( type:String, brand: String, transmission: String)


I am using
slick
to query a database that contains all of the columns in the case class and I get a query result like this (a list of objects):

List(Vehicle(car, audi, automatic), Vehicle(truck, toyota, automatic), Vehicle(motorcycle, bmw, manual))


I want the result JSON to look like this:

{
"vehicles" : [
{
"type" : "car",
"brand" : "audi",
"transmission" : "automatic",
},
{
"type" : "truck",
"brand" : "toyota",
"transmission" : "automatic",
},
{
"type" : "motorcycle",
"brand" : "bmw",
"transmission" : "manual",
}
]
}


Now to achieve that, I can easily use a mutable list and map my DB result one by one and build out a JSON like that. Since I am already using the Play Framework, writing out JSON is a piece of cake. But, I would like to do things in a more functional way and without using any mutable variables.

How do I read the List of objects from the DB result and put it together like in the result JSON?

Answer Source

Define Json Format for Vehicle and then you can convert List[Vehicle] to Json automatically by Json.toJson(vehicles)

import play.api.libs.json._

case class Vehicle( type:String, brand: String, transmission: String)

object Vehicle {
  implicit val vehicleFormat = Json.format[Vehicle]
}

//this will be slick function which gets data from database
def getVehiclesFromDB: Future[List[Vehicle]] = Future(List(Vehicle("a", "b", "c"), Vehicle("d", "e", "f")))

Inside the Controller

@singleton
class Application @Inject() (vehiclesRepo: VehiclesRepo) extends Controller {
  def getVehicles = Action.async { 
    vehiclesRepo.getVehiclesFromDB.map { vehicles =>
     Ok(Json.toJson(vehicles))
    }
  }
}