Generic Spray Client pipeline method with SprayJson.

915 views
Skip to first unread message

Dmitry

unread,
Mar 11, 2014, 5:52:42 PM3/11/14
to spray...@googlegroups.com
Hello,

I'm working on client library wrapper for an api and would like to have the following generic pipeline processing method:

  def request[T: Manifest](req: MyRequest): MyResponse[T] = {
    val pipeline = sendReceive ~> unmarshal[T]

   ......

    val responseFuture = pipeline { req }
    responseFuture. map {
    ....
    } // return MyResponse[T]
  }

You can see that I use Manifest to provide type information to successfully apply unmarchal[T]
It works if I use liftJson library with providing implicits:

implicit val liftJsonFormats: Formats = Serialization.formats(NoTypeHints) ++ JodaTimeSerializers.all

For some reason I would like to use SprayJson and do the following in spray.examples:

object MyJsonProtocols extends DefaultJsonProtocol {
  implicit val MyClassFormat = jsonFormat2(MyClass)
}

 and import it with 

import MyJsonProtocols._
import SprayJsonSupport._

But unfortunately I get the following issue: 

could not find implicit value for evidence parameter of type spray.httpx.unmarshalling.FromResponseUnmarshaller[T]
[error]     val pipeline = sendReceive ~> unmarshal[T]

Can you please advise the way to implement generic pipeline processing with SprayJson? Thanks!

Mathias Doenitz

unread,
Mar 12, 2014, 5:04:47 AM3/12/14
to spray...@googlegroups.com
Dmitry,

if you look at the signature of the `unmarshal[T]` stage that you put into your pipeline you’ll see that it looks like this:

def unmarshal[T: FromResponseUnmarshaller]: HttpResponse ⇒ T =

It requires a `FromResponseUnmarshaller` type bound, not a `Manifest`.
Just changing the `Manifest` bound in your code to `FromResponseUnmarshaller` should be all that is required to solve the problem.

Cheers,
Mathias

---
mat...@spray.io
http://spray.io
> --
> You received this message because you are subscribed to the Google Groups "spray.io User List" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to spray-user+...@googlegroups.com.
> Visit this group at http://groups.google.com/group/spray-user.
> To view this discussion on the web visit https://groups.google.com/d/msgid/spray-user/d0cfa54a-d7d1-4a94-9878-9aaa732d7a7e%40googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

Message has been deleted

Dmitry

unread,
Mar 12, 2014, 5:12:56 AM3/12/14
to spray...@googlegroups.com
Hi Mathias,

Danke, I ll try it again tonight. I investigated what unmarshal[T] requires and tried to satisfy implicit conversions for RootJsonFormat[T] and FromResponseUnmarshaller, but it didn't work. I ll update later on.

Viktoriya

unread,
Apr 1, 2014, 8:34:25 AM4/1/14
to spray...@googlegroups.com
Hi Dmitry,

Have you managed to solve it?

I'm trying to do the same thing, and define 

def pipeline[T] = sendReceive ~> unmarshal[T]

but it doesn't work with the same error :


could not find implicit value for evidence parameter of type spray.httpx.unmarshalling.FromResponseUnmarshaller[T]
[error]     def pipeline[T] = sendReceive ~> unmarshal[T]
[error]                                                ^

As I understand it is due to implicit transformations of T to FromResponseUnmarshaller  in TransformerPipelineSupport trait?

If someone could share the correct way to do this, I would be grateful.

Viktoriya

Dmitry

unread,
Apr 1, 2014, 8:45:26 AM4/1/14
to spray...@googlegroups.com
Hi Viktoriya,

I have. You can see it here: 
called from 

sorry for a dirty code - it's just a half-baked experiment. Basically you need to provide implicit when calling your generic method and require T: FromResponseUnmarshaller: Manifest in the method declaration. I finally switched to lift-json but that solution worked for me.

Alexander van Olst

unread,
Jun 20, 2016, 9:11:49 AM6/20/16
to spray.io User List
This is a very late response, but since this discussion ranks pretty high up here is my solution (withoutthe Manifest):

Since the compiler wants proof that there exists a FromResponseUnmarshaller[T], you can just add this as a parameter to your pipeline function like so:

val pipeline[T]()(implicit ev: FromResponseUnmarshaller[T]) = sendReceive ~> unmarshal[T]


Then wherever you make use of the pipeline you should have the particular implicit FromResponseUnmarshaller and you can just:

pipeline().apply(req)
Reply all
Reply to author
Forward
0 new messages