Return exact answer / title?

From the client side of webapp, I ended up on a server route, which is just a wrapper for a third-party API. Using dispatch, I try to make the server-side request the correct header exact and the response of the third-party API to the AJAX client call.

When I do this:

val req = host("third-pary.api.com, 80) val post = req.as("user", "pass") / "route" << Map("key" -> "akey", "val" -> "aval") Http(post > as.String) 

I always see a 200 response being returned to an AJAX call (sort of expected). I saw the Either syntax, but I really am Any more, as this is just the exact answer and the title. How will it be written?

I should mention that I use Scalatra on the server side, so the local route:

 post("/route") { } 

EDIT:

Here is a suggested example of the match I'm playing with, but the match syntax doesn't make sense - I don't care if there is an error, I just want to return it. In addition, I cannot force BODY to return this method.

 val asHeaders = as.Response { response => println("BODY: " + response.getResponseBody()) scala.collection.JavaConverters.mapAsScalaMapConverter( response.getHeaders).asScala.toMap.mapValues(_.asScala.toList) } val response: Either[Throwable, Map[String, List[String]]] = Http(post > asHeaders).either() response match { case Left(wrong) => println("Left: " + wrong.getMessage()) // return Action with header + body case Right(good) => println("Right: " + good) // return Action with header + body } 

Ideally, solutions return a Scalatra ActionResult(responseStatus(status, reason), body, headers) .

+2
source share
2 answers

It is actually very easy to get response headers when using Dispatch. For example, from 0.9.4:

 import dispatch._ import scala.collection.JavaConverters._ val headers: java.util.Map[String, java.util.List[String]] = Http( url("http://www.google.com") )().getHeaders 

And now, for example:

 scala> headers.asScala.mapValues(_.asScala).foreach { | case (k, v) => println(k + ": " + v) | } X-Frame-Options: Buffer(SAMEORIGIN) Transfer-Encoding: Buffer(chunked) Date: Buffer(Fri, 30 Nov 2012 20:42:45 GMT) ... 

If you do this often, it is better to encapsulate it, for example:

 val asHeaders = as.Response { response => scala.collection.JavaConverters.mapAsScalaMapConverter( response.getHeaders ).asScala.toMap.mapValues(_.asScala.toList) } 

Now you can write the following:

 val response: Either[Throwable, Map[String, List[String]]] = Http(url("http://www.google.com") OK asHeaders).either() 

And you have error checking, beautiful immutable collections, etc.

+5
source

We needed the response body of failed API requests, so we came up with this solution:

Define your own ApiHttpError class with code and body (for body text):

 case class ApiHttpError(code: Int, body: String) extends Exception("Unexpected response status: %d".format(code)) 

Define OkWithBodyHandler same way as used in the displatch source:

 class OkWithBodyHandler[T](f: Response => T) extends AsyncCompletionHandler[T] { def onCompleted(response: Response) = { if (response.getStatusCode / 100 == 2) { f(response) } else { throw ApiHttpError(response.getStatusCode, response.getResponseBody) } } } 

Now, next to your code call that can be thrown and an exception ( API call), add implicit override in ToupleBuilder (again similar to the source code) and call OkWithBody on request

 class MyApiService { implicit class MyRequestHandlerTupleBuilder(req: Req) { def OKWithBody[T](f: Response => T) = (req.toRequest, new OkWithBodyHandler(f)) } def callApi(request: Req) = { Http(request OKWithBody as.String).either } } 

From now on, either fetching will give you [Throwable, String] (using as.String) , and Throwable us our ApiHttpError with code and body .

Hope this helped.

0
source

All Articles