How do you get response code when using Custom Object instead of Httpresponse

962 views Asked by At

When I use

val pipeline: HttpRequest => Future[HttpResponse] = addHeader(.......) ~> sendReceive ~>       unmarshal[HttpResponse]        

then I can get the Status code as it an object of HttpResponse using

val futureResponse = pipeline(Post(url, body)) futureResponse.map(_.status)

However, when I use a custom unmarshaller as:

val pipeline: HttpRequest => Future[MyResponse] = addHeader(.......) ~> sendReceive ~>      unmarshal[MyResponse]

using

val myfutureResponse = pipeline(Post(url, body))
myutureResponse.map(_.status)

doesn't compile as it cannot find status. How do I get the status code here? I need to use a custom unmarshaller to be able to deserialize my json result.

2

There are 2 answers

0
Sheggetin On BEST ANSWER

Finally I found an answer based on your suggestion

private def unmarshal[T: Unmarshaller](response: HttpResponse): T = {
response.entity.as[T] match {
  case Right(value) => value
  case Left(error)  ⇒ throw new PipelineException(error.toString)
}

}

I changed my pipeline method to be

val pipeline: HttpRequest => HttpResponse = addHeader(.......) ~> sendReceive
val searchResponse = pipeline(Post(urlwithpath, queryString)).map {
  response => response.status match {
    case StatusCodes.OK =>
      Some(unmarshal[MyResponse](response))
    case StatusCodes.NotFound => print(StatusCodes.NotFound)
   }
}

Now that I have got this out of the way, I will learn the API properly

4
Aldo Stracquadanio On

If you hardcode the un-marshaller in the pipeline there is no way you can get the status code. You will still get failures code as they will be part of the exception that will cause the Future to fail.

If you really want to keep that information AND use an un-marshaller in your pipeline you will need to write your own un-marshaller that can provide you with a response of this sort:

case class Wrapper[T](response: T, status: StatusCode)

val pipeline: HttpRequest => Future[Wrapper[MyResponse]] = addHeader(.......) ~> sendReceive ~> myUnmarshall[MyResponse]

This could get quite tricky if you don't know the spray internals. Another option is to not hardcode the unmarshall bit in your pipeline and de-serialise the JSON manually.