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