# 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.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://devon-miller.gitbook.io/my-dispatch-user-notes/chapter_2/just_handlers.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
