I am trying to write a general extractor to parse a Json POST body using spray and json spray.
However, I'm struggling to get it to work with more than one model. Here's the case statement in the service object:
import MyJsonProtocol._ ... def receive = { case Post (Routes.person.post, p: Person) => sender ! Ok(Actions.person.post(p)) case Get (Routes.foo.forId(x)) => sender ! Ok(x) case _ => sender ! Ok("No handler") }
And here is the extractor I wrote (this works as long as there is only JsonReader for one model in the case statement):
//NB. Json.parse returns an Option[T] object Post extends Request { def unapply[T:JsonReader](req: HttpRequest): Option[(String, T)] = req match { case HttpRequest(POST, url, _, HttpBody(_, body), _) => Json.parse[T](body.asString).map((url, _)) case _ => None } }
However, as soon as I add a new model (and its associated JsonReader), the code no longer compiles with this error:
ambiguous implicit values: [error] both value personFormat in object Json of type => spray.json.RootJsonFormat[com.rsslldnphy.foam.models.Person] [error] and value animalFormat in object Json of type => spray.json.RootJsonFormat[com.rsslldnphy.foam.models.Animal] [error] match expected type spray.json.JsonReader[T] [error] case Post (Routes.person.post, p: Person) => sender ! Ok(Actions.person.post(p))
The fact that the common JsonReaders types are different seems to be lost. Is this an erasure of this type? Is there any way around this to get what I want?
Here's the full, compiling project code so far with a comment in ExampleService that explains what causes it to break: github.com/rsslldnphy/foam , your help is appreciated, thanks.
Or if what I want is currently not possible, can anyone suggest an alternative approach?