Since dispatch is a http client, we need a http server to connect to and return results for these user notes.
We can use akka http to create a server. Humorously, akka http also include a http client that is capable if issuing http commands just like dispatch and replaces both dispatch and http-async-client. More on this topic later.
The example server allows you to play around with the requests and the responses on the server side and understand what dispatch, and hence, async-http-client is up to when it builds its requests. By changing out the "routes" below, you can alter the example server to return anything you want. By default its an echo server and it echoes, in akka http format, the request and response. akka parsess the request and responses into akka specific data structures but is good enough for understanding what a real http server sees when programming your client.
An Example Server
I put together an example server based on akka http. It is listed out below but you can also find it on github. You can clone it and run it yourself. I have included both the source and the build.sbt and plugins.
You can execute the server in a shell by running sbt run or "pack" the project into an executable using sbt pack and the running the script that starts the server.
package exampleimport scala.language._import akka.actor._import akka.http.scaladslimport scaladsl._import scaladsl.serverimport scaladsl.model._import server._import server.Directives._import akka.streamimport stream._import stream.scaladsl._import scaladsl.model.StatusCodes._import com.typesafe.config.ConfigFactoryimport scala.io.StdInimport com.beust.jcommander._import com.typesafe.scalalogging.LazyLoggingimport scala.xml.XMLimport XML._import akka.http.scaladsl.marshallers.xml.ScalaXmlSupport._object Args {@Parameter(names = Array("-h", "--help"), help =true)var help: Boolean =false}object Server extends LazyLogging {implicitval system = ActorSystem()implicitval materializer = ActorMaterializer()implicitval ec = system.dispatcherval route = logRequestResult("example-server") { pathEndOrSingleSlash { get { complete(<h1>you have reached the example server</h1>) } } ~ path("echo") { get { extractRequest { req => complete(req.toString) } } } ~ post { complete("POST succeeded") } }defmain(args: Array[String]): Unit = {val j =new JCommander(Args, args.toArray: _*)if (Args.help) {val sb =new java.lang.StringBuilder() j.setProgramName("crmauth") j.usage(sb) // only way to get pre-formatted usage info sb.append("An application.conf can be use to specify some parameters.") println(sb.toString) system.terminate()return }val config = ConfigFactory.load()val ip = config.getString("http.host")val port = config.getInt("http.port")val server = ip +":"+ portval binding = Http().bindAndHandle(route, ip, port) binding onFailure {case ex: Exception => logger.error(s"Error binding $server", ex) system.terminate()return } println(s"Started server on $server.\nPress ENTER to stop.") StdIn.readLine() binding flatMap { _.unbind() } onComplete { _ => system.terminate() } }}
akka {//loglevel = DEBUG}http { host ="localhost" host =${?HOST} port =9000 port =${?HTTP_PORT}}`
Uncommenting the loglevel prints out the request and response for each request made to the server.
With this example server, you can alter the routes to create server content that your dispatch client can connect to and test receiving in case you run into difficult with your own http service. For example, you could add:
... } ~ path("myjson") { complete("{}") }
to add json content to the example server and retrieve it from the dispatch client for testing. We make various modifications to the basic server listed above so check out the git source for additional routes that may have been added after I typed in this section :-)