Dispatch 

Dispatch is a library for asynchronous HTTP interaction. It provides a Scala vocabulary for Java’s async-http-client. The latest release version is 0.13.2.

This documentation walks through basic functionality of the library. You may also want to refer to its scaladocs

Diving in 

To start playing with Dispatch on a console you can use one of two tools. The Ammonite REPL or sbt’s console functionality. When you’re ready to include Dispatch in an actual project, just follow the instructions for adding the Dispatch dependencies to build.sbt below.

Ammonite REPL 

To get started with Dispatch in the Ammonite REPL, execute amm at your shell and then paste in the following.

# only include this first line if you want all
# of the debugging log output, otherwise omit
import $ivy.`ch.qos.logback:logback-classic:1.2.3`

import $ivy.`net.databinder.dispatch::dispatch-core:0.13.2`

Your environment now has everything in scope you need to play with dispatch in the console.

SBT 

Once you have sbt installed, Dispatch is two steps away. Open a shell and change to an empty or unimportant directory, then add the following content to a file named build.sbt:

libraryDependencies ++= Seq(
  // For the console exercise, the logback dependency
  // is only important if you want to see all the
  // debugging output. If you don't want that, simply
  // omit it.
  "ch.qos.logback"          %  "logback-classic" % "1.2.3",
  "net.databinder.dispatch" %% "dispatch-core"   % "0.13.2"
)

Then invoke sbt console from your shell. After “the internet” has downloaded, you’re good to go. the above settings in build.sbt are also the settings you’ll use to add dispatch to your project when it comes time to actually use it in a production application.

Defining requests 

We’ll start with a very simple request.

import dispatch._, Defaults._
val svc = url("http://api.hostip.info/country.php")
val country = Http.default(svc OK as.String)

The above defines and initiates a request to the given host where 2xx responses are handled as a string. Since Dispatch is fully asynchronous, country represents a future of the string rather than the string itself.

Deferring action 

You can act on the response once it’s available with a for-expression.

for (c <- country)
  println(c)

This for-expression applies to any successful response that is eventually produced. If no successful response is produced, nothing is printed. This is how for-expressions work in general. Consider a more familiar example:

val opt: Option[String] = None
for (o <- opt)
  println(o)

An option may or may not contain a value, just like a future may or may not produce a successful response. But while any given option already knows what it is, a future may not. So the future behaves asynchronously in for-expressions, to avoid holding up operations subsequent that do not depend on its value.

Demanding answers 

As with options, you can require that a future value be available at any time:

val c = country()

But the wise use of futures defers this operation as long as is practical, or doesn’t perform it at all. To see how, keep reading.

Fork me on GitHub