Processing the FullResponse 

Once you build a Request value, you can pass it to HttpClient to execute the request using run, download, processFull, runStream methods.

http.run(r, f) 

There are many methods on HttpClient, but probably the most useful one is http.run(r, f) method. As we saw in Basic Concepts page this take a Request value, and a function FullResponse => A.

Gigahorse provides Gigahorse.asString function to return Future[String], but we can imagine this could be expanded to do more.

Another thing to note is that run method will only accept HTTP 2XX statuses, and fail the future value otherwise. (By default 3XX redirects are handled automatically)

Post-processing a Future 

In addition to passing in a function, a Future can easily be post-processed by mapping inside it.

scala> import gigahorse._, support.asynchttpclient.Gigahorse
import gigahorse._
import support.asynchttpclient.Gigahorse

scala> import scala.concurrent._, duration._
import scala.concurrent._
import duration._

scala> import ExecutionContext.Implicits._
import ExecutionContext.Implicits._

scala> Gigahorse.withHttp(Gigahorse.config) { http =>
         val r = Gigahorse.url("http://api.duckduckgo.com").get.
           addQueryString(
             "q" -> "1 + 1",
             "format" -> "json"
           )
         val f0: Future[FullResponse] = http.run(r, identity)
         val f: Future[String] = f0 map { Gigahorse.asString andThen (_.take(60)) }
         Await.result(f, 120.seconds)
       }
res0: String = {"DefinitionSource":"","Heading":"1+1","ImageWidth":0,"Relat

Whenever an operation is done on a Future, an implicit execution context must be available — this declares which thread pool the callback to the future should run in.

For convenience there’s an overload of run that takes only the Request parameter.

Lifting the FullResponse to Either 

One of the common processing when dealing with a Future that can fail is to lift the inner A value to Either[Throwable, A].

There’s a convenient website called http://getstatuscode.com/ that can emulate HTTP statuses. Here’s what happens when we await on a failed Future.

scala> Gigahorse.withHttp(Gigahorse.config) { http =>
         val r = Gigahorse.url("http://getstatuscode.com/500")
         val f = http.run(r, Gigahorse.asString)
         Await.result(f, 120.seconds)
       }
gigahorse.StatusError: Unexpected status: 500
  at gigahorse.StatusError$.apply(StatusError.scala:29)
  at gigahorse.support.asynchttpclient.OkHandler$class.onStatusReceived(OkHandler.scala:27)
  at gigahorse.support.asynchttpclient.OkHandler$FullOkHandler.onStatusReceived(OkHandler.scala:32)
  at gigahorse.support.asynchttpclient.AhcHttpClient$$anon$2.onStatusReceived(AhcHttpClient.scala:78)
  at org.asynchttpclient.netty.handler.HttpHandler.exitAfterHandlingStatus(HttpHandler.java:89)
  at org.asynchttpclient.netty.handler.HttpHandler.notifyHandler(HttpHandler.java:75)
  at org.asynchttpclient.netty.handler.HttpHandler.handleHttpResponse(HttpHandler.java:131)
  at org.asynchttpclient.netty.handler.HttpHandler.handleRead(HttpHandler.java:184)
  at org.asynchttpclient.netty.handler.AsyncHttpClientHandler.channelRead(AsyncHttpClientHandler.java:76)
  at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:367)
  at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:353)
  at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:346)
  at io.netty.channel.ChannelInboundHandlerAdapter.channelRead(ChannelInboundHandlerAdapter.java:86)
  at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:367)
  at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:353)
  at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:346)
  at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:102)
  at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:367)
  at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:353)
  at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:346)
  at io.netty.channel.CombinedChannelDuplexHandler$DelegatingChannelHandlerContext.fireChannelRead(CombinedChannelDuplexHandler.java:435)
  at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:293)
  at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:280)
  at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:396)
  at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:248)
  at io.netty.channel.CombinedChannelDuplexHandler.channelRead(CombinedChannelDuplexHandler.java:250)
  at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:367)
  at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:353)
  at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:346)
  at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1294)
  at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:367)
  at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:353)
  at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:911)
  at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:131)
  at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:652)
  at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:575)
  at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:489)
  at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:451)
  at io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:140)
  at io.netty.util.concurrent.DefaultThreadFactory$DefaultRunnableDecorator.run(DefaultThreadFactory.java:144)
  at java.lang.Thread.run(Thread.java:745)

Gigahorse provides a mechanism called Gigahorse.asEither to lift the inner A value to Either[Throwable, A] as follows:

scala> Gigahorse.withHttp(Gigahorse.config) { http =>
         val r = Gigahorse.url("http://getstatuscode.com/500")
         val f = http.run(r, Gigahorse.asEither)
         Await.result(f, 120.seconds)
       }
res2: Either[Throwable,gigahorse.FullResponse] = Left(gigahorse.StatusError: Unexpected status: 500)

asEither can be mapped over as a right-biased Either.

scala> Gigahorse.withHttp(Gigahorse.config) { http =>
         val r = Gigahorse.url("http://getstatuscode.com/200")
         val f = http.run(r, Gigahorse.asEither map {
           Gigahorse.asString andThen (_.take(60)) })
         Await.result(f, 120.seconds)
       }
res3: Either[Throwable,String] =
Right(<!DOCTYPE html>
<html lang="en">
    <head>
        <meta ch)

http.processFull(r, f) 

If you do not wish to throw an error on non-2XX responses, and for example read the body text of a 500 response, use processFull method.

scala> Gigahorse.withHttp(Gigahorse.config) { http =>
         val r = Gigahorse.url("http://getstatuscode.com/500")
         val f = http.processFull(r, Gigahorse.asString andThen (_.take(60)))
         Await.result(f, 120.seconds)
       }
res4: String =
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta ch