I am very new to spray.io and scala for that matter, so I apologize in advance if I didn't get the terminology right here in regards to unmarshalling.
I'm trying to get my hands on a HTTP POST response using a pipeline, it's expected to fail because I need an authorization header, but let's ignore that for now.
If I use the chrome extension Postman to POST to the url, I get this response, plain and simple json:
{"status":"error","message":"You must identify yourself to access this resource.","url":"https://scrive.com/login"}
So I started with creating my own case class for this response, and implemented my own JsonProtocol, to unmarshal the response.
case class CreateFromTemplateResult(status: String, message: String, url: String)
object ScriveJsonProtocol extends DefaultJsonProtocol {
implicit val createFromTemplateResponseFormat = jsonFormat3(CreateFromTemplateResult)
}
So now I'm all set, to run my pipeline, and recieve the response.
val pipeline = sendReceive ~> unmarshal[CreateFromTemplateResult]
val response = pipeline {
Post("https://api-testbed.scrive.com/api/v1/createfromtemplate/1")
}
response onComplete {
case Success(CreateFromTemplateResult(status, message, url)) =>
requestContext.complete("success")
case Failure(error) =>
requestContext.complete(error.getMessage)
}
The request completes and the onFailure case runs, but the error.getMessage is no longer json, as in the previous Postman example.
Status: 403 Forbidden
Body: {"status":"error","message":"You must identify yourself to access this resource.","url":"https://scrive.com/login"}
So my question becomes, how to I unmarshal the error returned and it's Body into my CreateFromTemplateResult case? Or simply into json would do as well. I don't know if my onSuccess case will work either, I want the same behaviour for them both. I want them to be in my defined CreateFromTemplateResult format.
case class CreateFromTemplateResult(status: String, message: String, url: String)
Thank you very much for your time, and again, I apologize for my bad terminology.
The error in this case is a UnsuccessfulResponseException
(you can see from the code to unmarshall
). So you can match this case specifically:
case Failure(e) => e match {
case ure: UnsuccessfulResponseException =>
val response = ure.response
if(response.status = StatusCodes.Forbidden)
complete(response.as[CreateFromTemplateResult])
else ...
case _ => ...
}
Alternatively you might prefer not to use unmarshal
at all (or to write your own unmarshal
), and just deal with the HttpResponse
that sendReceive
returns directly.