json - Scala + Reactivemongo: Controling custom readers/writers for REST-API -
i working on rest-api implemented in scalatra , using reactivemongo. persistent model implemented using case classes , thin repository layer uses common approach bson<->class mapping via documentreader/documentwriter (via implicit converters in case class companion object).
case class address(street: string, number: string, city: string, zip: string) object address{ implicit val addresshandler = macros.handler[address] implicit val addressfmt = json.format[address] }
the first formatter maps bson case classes second converts json (the output format of rest-api).
this fine , quite happy how nicely integrates.
in many cases though, don't need operate on domain objects (case class instances) , want stream data coming data base write http response. intermediate conversions overhead in scenarios. want control fields exposed (i once used yoga , jackson in java project).
possible solutions to:
- have generic repository converts map structure intermediate format.
- control implicit converters available driver on per-query basis , write case classes different "views"
- use bsondocument intermediate format , make rest layer understand bson via bson=>string conversion.
i wonder best approach , if has experience particular scenario. maybe missing out option? feedback welcome.
to control fields exposed, have write readers , writers. below example extracted project https://github.com/luongbalinh/play-mongo.
import java.time.zoneddatetime case class user(override val id: option[long] = none, firstname: string, lastname: string, age: int, active: boolean, createddate: option[zoneddatetime] = none, updateddate: option[zoneddatetime] = none ) extends idmodel[user] { override def withnewid(id: long): user = this.copy(id = some(id)) } object user { import play.api.libs.functional.syntax._ import play.api.libs.json._ implicit val userreads: reads[user] = ( (jspath \ "id").readnullable[long] , (jspath \ "firstname").read[string] , (jspath \ "lastname").read[string] , (jspath \ "age").read[int] , (jspath \ "active").read[boolean] , (jspath \ "createddate").readnullable[zoneddatetime] , (jspath \ "updateddate").readnullable[zoneddatetime] )(user.apply _) implicit val userwrites: writes[user] = ( (jspath \ "id").writenullable[long] , (jspath \ "firstname").write[string] , (jspath \ "lastname").write[string] , (jspath \ "age").write[int] , (jspath \ "active").write[boolean] , (jspath \ "createddate").writenullable[zoneddatetime] , (jspath \ "updateddate").writenullable[zoneddatetime] )(unlift(user.unapply)) }
Comments
Post a Comment