summerNight summerNight - 1 month ago 11
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

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))
    }
  }
}