Scala playfamework - how to wrap one JSON string with another?
Scala playfamework - how to wrap one JSON string with another?
I have JSON data coming from two different API endpoints. The first JSON contains data about stores and the second contains data on transactions(sales).
For each store Id I'm getting an array of transactions and parsing it into JsValue. So I have a store Jsvalue representing the certain store and transactions JsValue, representing an array of transactions for the store. Then I stringify the JsValues:
JsValue
store
transactions
(Json.stringify(storeJsValue), Json.stringify(transactionsJson))
Printed result of the stringified JsValues for the above Array[(String, String)]:
({"store_id":"01","name":"Store_1"}, [{"saleId": 12, "name": "New name1", "saleType": "New Type1"]}, {"saleId": 222, "name": "Some name1", "saleType": "SomeType5"})
({"store_id":"02","name":"Store_2"}, [{"saleId": 123, "name": "New name2", "saleType": "New Type2"}])
({"store_id":"03","name":"Store_3"}, [{"saleId": 1234, "name": "New name3", "saleType": "New Type3"}, {"saleId": 333, "name": "Some name3", "saleType": "SomeType3"}])
Finally I want to produce a resulting string so that the store data wraps its transactions data and looks like this:
"{store:"storeJson",transactions:"+ transactionsJson + "}"
What is the best way to achieve this with Play Json?
4 Answers
4
One way to do this would be converting the jsons to objects, create a new object with the attributes "store" and "transactions" and transform it to JSON again.
That way you would get:
{
"store": {
"store_id":"01",
"name":"Store_1"
},
"transactions": [
{
"saleId": 12,
"name": "New name1",
"saleType": "New Type1"
},
{
"saleId": 222,
"name": "Some name1",
"saleType": "SomeType5"
}
]
}
Your class:
case class MyClass( store : Store, transactions : Array[Sales]) {
.....
}
In Play you can use the Json Reads/Writes helpers to convert from a case class to Json and vice versa. So, for your example:
Reads/Writes
case class
Json
case class Store(store_id: String, name: String)
Then if you have a Json and want to turn it into Store case class you need a 'reader':
Store
val storeReads: Reads[Store] = Json.reads[Store]
After that you can read the content of Json as a String and turn it into the case class (assuming storeJson is a val that contains the content of Json):
storeJson
val toStoreCaseClass: JsResult[Store] = Json.fromJson[Store](json.parse(storeJson))
If you want to turn the case class into Json, then you use writes:
val storeWrites: OWrites[Store] = Json.writes[Store]
Now assume that you have a val storeInstance of type Store, you turn it into Json, by the following line:
storeInstance
Store
Json.toJson(storeInstance)
You can do the same thing for transactions.
Ok Now that you have case classes, you can morph them into whatever format you want by using the usual collections commands (e.g., map, filter, etc.). You can even have an additional more generic case class that holds the format you want to achieve (with its read/writes); and do your data operations, and then at last turn them into Json.
map
filter
I've managed to achieve the desired result.
val store = Json.stringify(storeJsValue)
val transactions = Json.stringify(transactionsJsValue)
val storeWithTransactions: String = s"{store: $store , transactions: $transactions}"
This way I'm getting a string with data on a store and all its transactions. So I just iterate over stores and for each store Id get its transactions from another endpoint. Then concatenate stringified JsValues of store and transactions collecting the resulting Strings into Array[String].
store
transactions
you have two json values, you can make a new object out of them:
val store = Json.stringify(storeJsValue)
val transactions = Json.stringify(transactionsJsValue)
val storeWithTransactions: String = Json.stringify(Json.obj(
"store" -> store,
"transactions" -> transactions))
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.