# Just Handlers

## Just Handlers

If you issue a request and receive a response, you need to create a handler. dispatch provides some handy handlers to convert the response body to a string, XML or using whatever function you have that converts a request to an output value.

Some of the `as.*` that you have out of the box include:

* `as.Response`: Returns the raw response object.
* `as.String.utf8`: Returns utf8 string.
* `as.Bytes`: Returns bytes.
* `as.File(yourfile)`: Redirects the body to a file.
* `as.XML`: Creates XML a scala scala.xml.Elem.

You can also pass in your own function that handles a full async-http-client Response and returns some value derived from it. For example, the response body is available as `Reseponse.getResponseBody` so you could do:

```scala
@ Http(host("localhost:9000") > { _.getResponseBody} ) onComplete println 
Success(<h1>you have reached the example server</h1>)
```

which does the same thing as `as.String` but illustrates the syntax somewhat. You could also define your function elsewhere and use it instead of `{_.getResponseBody}`. You should notice that this function only runs after the entire response has been received so you lose as-you-get-it processing capabilities using this approach. You can also provide your own `AsyncHandler` directly and use `>`.

Generally, you will wan to use `OK` and your handler, a function `Response => T` so that your function only runs if the call was successful:

```scala
@ Http(host("localhost:9000") OK { _.getResponseBody} ) onComplete println 
Success(<h1>you have reached the example server</h1>)
@ Http(host("localhost:9000") OK { _.getStatusCode} ) onComplete println 
Success(200)
```

## The `>` function and `AsyncHandler`

The `>` function to create a handler is overloaded. You can provide a function, like we did in the last section, or an `AsyncHandler`.

There is also a handler at `at.stream.Lines` that takes a `String => T` function parameter that processes each line of response using the function parameter. If we alter our example-server program to return a well known set of lines:

```scala
} ~ path("lines") { 
        get { 
          complete("1\n2\n3\n")
        }
      }
```

then we can use it like:

```scala
@ Http(host("localhost:9000") / "lines"  > as.stream.Lines(println)) onComplete println 
1
2
3
Success(())
```

Using the handler this way is clearly being used for its side-effects. We also used the `>` method which directly takes an async-http-client `AsyncHandler` directly. When you want explicit control over response processing you would write your own `AsyncHandler`. You would use this, for example, to interface to a processing library like [monix](https://github.com/monixio/monix).

## json response handling

XML is a bit deprecated today and the new hotness, for the past decade actually, has really been json.

dispatch has json support for a few libarries but does not restrict you to only using them. Everyone uses a different json library it seems.

First, we need to alter our example server to return some json, the route will add is:

```scala
~ path("json") { 
        get { 
          complete("""{ "result" : "hello world"}""")
        }
      }
```

There are a few add-ons for json support provided by dispatch. We will show the one based on lift json, which has not been updated in a long time, but still works of course:

```scala
load.ivy("net.databinder.dispatch" %% "dispatch-core" % "0.11.3")
load.ivy("net.databinder.dispatch" %% "dispatch-lift-json" % "0.11.3")
load.ivy("net.liftweb" %% "lift-json" % "latest.release")

import scala.async.Async._
import dispatch._, Defaults._
import scala.concurrent.Await
import scala.concurrent.duration._
import net.liftweb.json._
import JsonDSL._

def callit() = Http(url(s"http://localhost:9000/json") OK as.lift.Json)

callit() onComplete { r => println(s"Result $r")}
```

You call the handle just like the other handlers, `as.lift.Json` and get back a json object:

```scala
@ callit() onComplete { r => println(s"Result $r")} 

Result Success(JObject(List(JField(result,JString(hello world)))))
```

The code for the handler suggests how simple it is to create your own json handler:

```scala
object Json extends (Response => JValue) {
  def apply(r: Response) =
    (dispatch.as.String andThen JsonParser.parse)(r)
}
```

You can see that using a combinator of `andThen` you can piece together the handlers and build on previous handlers. First `as.String` reads the response body and converts it to a String then `JsonParser.parse` parses that result. You can do this because a handler is defined as a function and you can compose functions.

The circe library is the new hotness for json parsing, based on argonaut but faster ([here](https://github.com/travisbrown/circe) on github). We just need a "handler" that takes a response to a circe json object, which is based on a cats library object since circe uses cats underneath:

```scala
load.ivy("net.databinder.dispatch" %% "dispatch-core" % "0.11.3")
Seq("io.circe" %% "circe-core",
  "io.circe" %% "circe-generic",
  "io.circe" %% "circe-parser") map (_ % "latest.release") foreach(load.ivy(_))

import dispatch._, Defaults._
import scala.concurrent.Await
import scala.concurrent.duration._

import com.ning.http.client.Response
import io.circe._, io.circe.generic.auto._, io.circe.parser._, io.circe.syntax._
import io.circe.{ Decoder, Encoder, Json }
import cats.data._

object CirceJson extends (Response => cats.data.Xor[ParsingFailure, Json]) {
  def apply(r: Response) =
    (dispatch.as.String andThen parse)(r)
}

def callit() = Http(url(s"http://localhost:9000/json") OK CirceJson)

callit() onComplete { r => println(s"Result $r")}
```

Which prints out:

```scala
Result Success(Right({
  "result" : "hello world"
}))
```

the result we expect.
