Last active
November 28, 2022 13:50
-
-
Save agemooij/f2e4075a193d166355f8 to your computer and use it in GitHub Desktop.
More advanced example of a custom spray-json format
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
implicit object ProductItemFormat extends RootJsonFormat[ProductItem] { | |
// some fields are optional so we produce a list of options and | |
// then flatten it to only write the fields that were Some(..) | |
def write(item: ProductItem) = JsObject( | |
List( | |
Some("product_number" -> item.productNumber.toJson), | |
item.ean.map(ean ⇒ "ean" -> ean.toJson), | |
Some("title" -> item.title.toJson), | |
item.description.map(description ⇒ "description" -> description.toJson), | |
Some("price" -> item.price.toJson), | |
Some("original_price" -> item.originalPrice.toJson), | |
item.scratchPrice.map(scratchPrice ⇒ "scratch_price" -> scratchPrice.toJson), | |
Some("scratch_price_to_display" -> item.scratchPriceToDisplay.toJson), // calculated field used by the UI | |
Some("size" -> item.size.toJson), | |
Some("availableStock" -> item.availableStock.toJson), | |
Some("shipping" -> item.shipping.toJson), | |
Some("vat_code" -> item.vatCode.toJson), | |
Some("vat_percentage" -> item.vatPercentage.toJson) | |
).flatten: _* | |
) | |
// we use the "standard" getFields method to extract the mandatory fields. | |
// For optional fields we extract them directly from the fields map using get, | |
// which already handles the option wrapping for us so all we have to do is map the option | |
def read(json: JsValue) = { | |
val jsObject = json.asJsObject | |
jsObject.getFields("product_number", "title", "price", "original_price", "size", "availableStock", "shipping", "vat_code", "vat_percentage") match { | |
case Seq(number, title, price, originalPrice, size, availableStock, shipping, vatCode, vatPercentage) ⇒ ProductItem( | |
number.convertTo[String], | |
jsObject.fields.get("ean").map(_.convertTo[String]), | |
title.convertTo[String], | |
jsObject.fields.get("description").map(_.convertTo[String]), | |
price.convertTo[Int], | |
originalPrice.convertTo[Int], | |
jsObject.fields.get("scratch_price").map(_.convertTo[Int]), | |
size.convertTo[Size], // notice that this just works (TM) as long as the required json format is implicitly available | |
availableStock.convertTo[Int], | |
shipping.convertTo[ShippingInfo], // notice that this just works (TM) as long as the required json format is implicitly available | |
vatCode.convertTo[String], | |
vatPercentage.convertTo[Int] | |
) | |
case other ⇒ deserializationError("Cannot deserialize ProductItem: invalid input. Raw input: " + other) | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Can you please give the sample json that goes with this? It will help us in understanding . Thanks .