Skip to content

Instantly share code, notes, and snippets.

@dacr
Last active June 25, 2023 15:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dacr/60000fb6fc81ee0ce2f6a38b8de43062 to your computer and use it in GitHub Desktop.
Save dacr/60000fb6fc81ee0ce2f6a38b8de43062 to your computer and use it in GitHub Desktop.
Fully asynchronous http client call with json streamed response using akka-http will work in all cases, even with chunked responses ! / published by https://github.com/dacr/code-examples-manager #25d85f17-5e12-4a74-ba8a-6aa629575af5/acc9d334dad26f7a16fa2fd943067ed7b3ac9403
// summary : Fully asynchronous http client call with json streamed response using akka-http will work in all cases, even with chunked responses !
// keywords : scala, actors, akka, http-client, client, json, json4s, http-stream, stream
// publish : gist
// authors : David Crosson
// license : Apache NON-AI License Version 2.0 (https://raw.githubusercontent.com/non-ai-licenses/non-ai-licenses/main/NON-AI-APACHE2)
// id : 25d85f17-5e12-4a74-ba8a-6aa629575af5
// created-on : 2018-06-19T19:10:04Z
// managed-by : https://github.com/dacr/code-examples-manager
// run-with : scala-cli $file
// ---------------------
//> using scala "2.13.8"
//> using dep "com.typesafe.akka::akka-http:10.2.7"
//> using dep "com.typesafe.akka::akka-stream:2.6.18"
//> using dep "de.heikoseeberger::akka-http-json4s:1.38.2"
//> using dep "org.json4s::json4s-jackson:4.0.3"
//// using lib "org.slf4j:slf4j-nop:1.7.32"
// ---------------------
/*
akka-http http client request with streamed json responses
---
scala in script mode using ammonite REPL (http://ammonite.io/)
---
take care this example is using the `toStrict(timeout)` method
to eagerly consume the entity and make it available in memory
*/
import akka.http.scaladsl._
import akka.http.scaladsl.model._
import akka.stream.scaladsl.Framing
import akka.util.ByteString
import scala.concurrent._
import scala.concurrent.duration._
import org.json4s.{DefaultFormats, JValue}
import org.json4s.jackson.JsonMethods._
import org.json4s._
object TestThat {
implicit val system = akka.actor.ActorSystem("MySystem")
implicit val executionContext = system.dispatcher
implicit val serialization = jackson.Serialization
implicit val formats = DefaultFormats
// curl -s -H "accept: application/json" http://httpbin.org/stream/99 | jq
val uri = s"http://httpbin.org/stream/99"
val futureResponse = Http().singleRequest(HttpRequest(uri = uri))
val strictEntity:Future[HttpEntity.Strict] = futureResponse.flatMap{_.entity.toStrict(3.seconds)}
val futureResult: Future[List[JValue]] = futureResponse.flatMap { response =>
response.entity.dataBytes
.via(Framing.delimiter(ByteString("\n"), maximumFrameLength = 256))
.map(buf => parse(buf.decodeString("UTF-8")))
.runFold(List.empty[JValue]) {case (acc,jv) => jv::acc}
}
val out = for {
results <- futureResult
} yield {
results.foreach{result => println(pretty(render(result))) }
}
// Do not exit before the future has completed ;)
def andWait():Unit = Await.ready(out, 10.seconds)
}
TestThat.andWait()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment