Skip to content

Instantly share code, notes, and snippets.

@soujiro32167
Last active October 10, 2020 03:35
Show Gist options
  • Save soujiro32167/6980312b8cd2abcbf11537188135dd75 to your computer and use it in GitHub Desktop.
Save soujiro32167/6980312b8cd2abcbf11537188135dd75 to your computer and use it in GitHub Desktop.
Http4s: decide response type based on stream head
import cats.effect.IO
import fs2.Stream
import org.http4s.{HttpRoutes, Request, Response}
import org.http4s.dsl.Http4sDsl
import scala.concurrent.ExecutionContext
import scala.util.control.NoStackTrace
val ec = ExecutionContext.global
implicit val cs = IO.contextShift(ec)
object Service extends Http4sDsl[IO] {
def streamResponse: Stream[IO, String] => IO[Response[IO]] = s =>
s.head.compile.lastOrError.flatMap(_ => Ok(s)).handleErrorWith(e => BadRequest(e.getMessage))
val routes = HttpRoutes.of[IO]{
case GET -> Root / "fail" =>
val body = Stream.bracket(IO(println("acquire...")))(_ => IO(println("release..."))).drain ++
Stream.raiseError[IO](new RuntimeException("boom!!!") with NoStackTrace).covaryOutput[String]
streamResponse(body)
case GET -> Root / "succeed" =>
val body = Stream.bracket(IO(println("acquire...")))(_ => IO(println("release..."))).drain ++
Stream[IO, String]("content")
streamResponse(body)
}
}
import org.http4s.implicits._
(for {
fail <- Service.routes.orNotFound.run(Request(uri = uri"/fail"))
content <- fail.bodyText.compile.string
} yield fail -> content).unsafeRunSync()
// acquire...
// release...
// res0: (org.http4s.Response[[+A]cats.effect.IO[A]], String) = (Response(status=400, headers=Headers(Content-Type: text/plain; charset=UTF-8, Content-Length: 7)),boom!!!)
(for {
success <- Service.routes.orNotFound.run(Request(uri = uri"/succeed"))
content <- success.bodyText.compile.string
} yield success -> content).unsafeRunSync()
// acquire...
// release...
// acquire...
// release...
// res1: (org.http4s.Response[[+A]cats.effect.IO[A]], String) = (Response(status=200, headers=Headers(Content-Type: text/plain; charset=UTF-8, Transfer-Encoding: chunked)),content)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment