Case classes for json formatting - with and without the object identifier


I am writing a play2 app that gets data via rest/json and stores it in mongodb using reactivemongo.

I am using a model built from case classes and implicit val myFormat = Json.format[myCaseClass]

Currently I have a case class for objects coming from mongodb. They contain the _id field and everything works. New objects coming in do naturally don't have this id field and so the Json.fromJson[myCaseClass](req.body) validator fails.

Do I really have to create another case class for new objects or is there a more DRY and elegant solution without duplicating the class and removing the _id?

I would use the parser combinator API and create a json format, or maybe even just a Reads[T], that handles incoming possibly id-less fields. Something like:

implicit val readsMyClass: Reads[MyClass] = (
  (__ \ "id").readNullable[Id] and
  (__ \ "someProperty").read[String]
)(create _)

def create(maybeId: Option[Id], someProperty: String) =
   MyClass(maybeId.getOrElse(...generate id...), someProperty)

See the docs for more info: