scalascala-dispatch

Basic usage of Dispatch 0.9


I want to POST to a URL, setting query parameters and headers and passing a raw string in the body. I then want to do the request and get the output string, so that i can convert it to JSON. I also want exception handling to respond to different kinds of errors (and handle redirects)

But Dispatch 0.9 is badly documented, breaks API with documented versions and is very quirky, so I cannot come up with a complete solution. I am utterly stuck, hence I ask for a lot.


This is all I can come up with, but setting the query params is weird:

val solr = host("localhost", 8983)
val req  = solr / "update" / "json" 
    setQueryParameters( Map( "commit" -> "true")) 
    setHeader( "Content-type", "application/json")
    setBody( a)

But setting the query parameters gives me a tough error:

<console>:14: error: type mismatch;
 found   : scala.collection.immutable.Map[java.lang.String,java.lang.String]
 required: com.ning.http.client.FluentStringsMap
       val req  = solr / "update" / "json"  setQueryParameters( Map( "commit" -> "true"))

Please help with setting the request completely: HTTPS, redirects, query parameters, headers and the POST method.

Also help with (synchronously, I want it that way) executing the request to get the body (and headers) and branching depending on the response code (200, 301, 302, 400, 500).


Solution

  • You're not too far off. The following should work for your request definition:

    import dispatch._
    
    val params = Map("commit" -> "true")
    val headers = Map("Content-type" -> "application/json")
    
    val solr = host("localhost", 8983)
    
    val req = solr / "update" / "json" << a <<? params <:< headers
    

    Or, less operatory-ily:

    val req = url("http://localhost:8983/update/json").POST
      .setBody(a)
      .addQueryParameter("commit", "true")
      .addHeader("Content-type", "application/json")
    

    Throw a .secure in there somewhere if you want to use HTTPS.

    You can get a promise (which essentially represents the result of a deferred request operation) like this:

    val result = Http(req OK as.String).either
    

    And then use it like this, for example:

    result() match {
      case Right(content)         => println("Content: " + content)
      case Left(StatusCode(404))  => println("Not found")
      case Left(StatusCode(code)) => println("Some other code: " + code.toString)
    }
    

    While I agree that the 0.9 documentation is sparse in some places, it does provide a very useful explanation of how to handle asynchronous request operations with promises.


    OP's addition: this bit completes this answer for me. This gets the response in a simple, blocking way.

    val response = Http(req)()
    val body response.getResponseBody