Requests and Handlers
The basic async-http-client needs both a request and a handler in order to make the remote call. dispatch allows you to execute a bare request because it creates an "identity" handler for you automatically. An identity handler does not do anything other than return the underlying netty response object:
In the above, I created a GET request using the url()
function and even though I did not have a handler defined, dispatch used the identity handler to issue the request. The return value is always a Future which I completed and printed out the body of the response. Since I was using the example http server, I got back the default response when accessing the root.
You can also create your own handler and execute the request with that. Dispatch provides help to create a handler. For example, it is very common to create a handler that allows a specific, expected response code to be recognized and if it is returned from the server, apply a function to the response body.
This prints out the same thing as the first example of course because the phrase OK as.String
uses dispatch to create a async-http-client AsyncHandler
that first looks for a specific status code, OK (which is the status code 200), and then convert the body to a String object. The phrase as.String
is a dispatch way of unmarshalling a response to a specific scala object. There are different unmarshallers available provided by dispatch to handle json or XML response bodies.
dispatch does not use an unmarshalling framework like akka http but keeps the unmarshaling concept very simple. In dispatch, a handler is really a function that converts a Response
into some object of type T
e.g. Response => T
. OK
in the example above is really a function that takes a "handler" function as an argument and returns a handler derived from async-http-client's AsyncHandler
. dispatch defines a default "OK handler" that looks for a status code of 200 and if found, calls the handler function that follows the OK
, in this case as.String
. You could write OK as.String
as OK(as.String)
.
The AsyncHandler
has to implement the onStatusReceived
and onComplete
and other handler calls that the async-http-client's class requires. dispatch provides convenient ways to create these handlers. An AsyncHandler
has multiple methods that must be satisfied and at some point either dispatch or yourself must implement these methods:
Under the hood, when the dispatch level client is called upon to issue the request, the dispatch client creates a promise that is completed with the response passed back up from async-http-client. The promise is completed with the response value after running through your handler function and it is this promise that provides you a scala Future
value to work with in scala. By importing Defaults._
a default execution context is created to execute the Future.
The newer async-http-client using jdk8 also allows future's to be used and while the syntax is not as expressive as in scala, you can get a java Future
back so it seems that async-http-client is moving in the direction of the dispatch which is to be expected.
Last updated
Was this helpful?