Firstly, you’ll almost certainly want to use a library for this. At work, I have been using akka http.

Hopefully this provides the minimal example without getting into trying to deal with sources and async maps.

Note that you’ll need the akka-http-core package.



import akka.actor.ActorSystem
import akka.http.scaladsl.Http
import akka.http.scaladsl.client.RequestBuilding
import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport
import akka.http.scaladsl.model.{ContentTypes, HttpEntity, HttpRequest, HttpResponse}
import akka.http.scaladsl.unmarshalling.Unmarshal
import akka.stream.ActorMaterializer
import spray.json._

import scala.concurrent._
import scala.concurrent.duration._
import scala.util.Try

object example
    extends SprayJsonSupport // These will allow us to unmarshal case classes automatically
    with DefaultJsonProtocol {

  // This is a sample way of modelling our response
  case class Foo(x: Int, y: String)
  implicit val fooMarshaller: RootJsonFormat[Foo] = jsonFormat2(Foo)


  // You'll also need these three
  implicit val actor: ActorSystem = ActorSystem()
  implicit val materializer: ActorMaterializer = ActorMaterializer()
  implicit val ec: ExecutionContextExecutor = actor.dispatcher

  def main(args: Array[String]): Unit = {

    val sampleResponse = """{"x":1, "y": "abc"}"""
    val fakeResponse = HttpResponse(
      entity = HttpEntity(ContentTypes.`application/json`, sampleResponse))
    val resp = concurrent.Promise.successful(fakeResponse).future
    
    // This is how you do an actual request
    val url = "https://dlow.me"
    val req: HttpRequest = RequestBuilding.Get(url)
    val realResponse: Future[HttpResponse] = Http().singleRequest(req)

    // It is nice that futures are composable.
    val eventualFoo = for {
      r <- resp
      d <- Unmarshal[HttpEntity](r.entity).to[Foo]
    } yield d

    // Synchronous code
    Try(Await.result(eventualFoo, 15.seconds)).fold(
      t => println(t),
      r => println(r)
    )
  }

}

Analysis

What I dislike most about the whole akka system is the need for these actors, materializer and execution context

Pitfalls

  • You will need to bring in all the akka family: akka-http, akka-stream

References

There are copy and pastable code here