Clients

A "client" contains various settings and parameters for connecting to a remote destination. A client is independent of the request and independent of the remote destination. A client is really about accessing the remote destination consistently.

A client is already created for you in dispatch that you can use without any further configuration. For the example below, do not forget to setup your amm as mentioned in an earlier section:

@ Http 
res5: Http.type = Http(com.ning.http.client.AsyncHttpClient@5563630d)

The default client has been setup with a specific user-agent named "dispatch" and adjusts the thread configuration. For example, it uses a different thread configuration if you are using dispatch from within sbt.

Http is just a case class that contains an AsyncHttpClient from async-http-client and includes a few functions to execute requests. The async-http-client client requires a request and a "handler" to execute the request--dispatch does as well. The dispatch layer helps you create a request and a handler in a more scala friendly way.

When you are done with a client, even the default one provided by dispatch, you should call:

@ Http.shutdown()

You should call this in your main program and not in a shutdown handler because shutdown is only called once threads are complete and .shutdown releases the threadpool that the client uses--hence shutdown would never be called in the jvm shutdown handler (scala.sys.addShutdownHook) if you added Http.shutdown to the jvm shutdown handler.

If you need to configure your async-http-client, use that scala level object in your program. For example, I often find it useful to have some filters on the client so I might do something like:

val myADFilter = new ADFilter(...)
val adhttp = Http.configure(_.addRequestFilter(myADFilter))

where ADFilter is a request filter defined on the async-http-client RequestFilter API:

public interface RequestFilter {
    public FilterContext filter(FilterContext ctx) throws FilterException
}

The funky syntax _.addRequestFilter(...) is part of the builder pattern used by dispatch to improve referentially transparency. The dispatch Http.configure methods takes a function that performs the configuraton on a instance of AsyncHttpClientConfig.Builder which is a Builder from the async-http-client library. The default client, Http, provides a async-http-client AsyncHttpClient that has a base config. By chaining onto this default config object, you can take a default configured client object, use its config, and build up your own modified configuration such as shown above where we added a filter that adds Active Directory headers to each request. Generally, you can add your own function { builder => ... } that performs multiple adjustments all at once. The function signature for .configure is Builder => Builder.

You can consult the async-http-client documentation for other parameters to set. A popular one is the timeout:

@ val myclient = Http.configure(_.setRequestTimeout(30000)) 
myclient: Http = Http(com.ning.http.client.AsyncHttpClient@5dcd3a19)

You can also use amm's autocompletion and just hit tab:

@ val myclient = Http.configure(_.[hit tab here]
!=                                             isInstanceOf                                   setConnectionTTL                               setMaxRedirects                                setUseProxyProperties
==                                             removeIOExceptionFilter                        setDisableUrlEncodingForBoundedRequests        setMaxRequestRetry                             setUseProxySelector
addIOExceptionFilter                           removeRequestFilter                            setEnabledCipherSuites                         setPooledConnectionIdleTimeout                 setUseRelativeURIsWithConnectProxies
addRequestFilter                               removeResponseFilter                           setEnabledProtocols                            setProxyServer                                 setUserAgent
addResponseFilter                              setAcceptAnyCertificate                        setExecutorService                             setProxyServerSelector                         setWebSocketTimeout
asInstanceOf                                   setAllowPoolingConnections                     setFollowRedirect                              setReadTimeout                                 toString
build                                          setAllowPoolingSslConnections                  setHostnameVerifier                            setRealm                                       |>
equals                                         setAsyncHttpClientProviderConfig               setIOThreadMultiplier                          setRequestTimeout
getClass                                       setCompressionEnforced                         setMaxConnections                              setSSLContext
hashCode                                       setConnectTimeout                              setMaxConnectionsPerHost                       setStrict302Handling

Using the Http.configure approach is also the way you configure SSL.

Last updated