Dispatch is a library for asynchronous HTTP interaction. It provides a Scala vocabulary for Java’s async-http-client. The latest release version is 2.0.0.
This documentation walks through basic functionality of the library. You may also want to refer to its scaladocs
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.
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.`org.dispatchhttp::dispatch-core:2.0.0`
Your environment now has everything in scope you need to play with dispatch in the console.
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",
"org.dispatchhttp" %% "dispatch-core" % "2.0.0"
)
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.
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.
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.
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.