diff --git a/build.sbt b/build.sbt index 4ed9bb7366..ddacd41ee1 100644 --- a/build.sbt +++ b/build.sbt @@ -675,7 +675,8 @@ lazy val http4sBackend = (projectMatrix in file("http4s-backend")) name := "http4s-backend", libraryDependencies ++= Seq( "org.http4s" %% "http4s-client" % http4s_ce3_version, - "org.http4s" %% "http4s-blaze-client" % "0.23.13" % Optional + "org.http4s" %% "http4s-ember-client" % "0.23.13" % Optional, + "org.http4s" %% "http4s-blaze-client" % "0.23.13" % Optional, ), evictionErrorLevel := Level.Info ) diff --git a/docs/backends/http4s.md b/docs/backends/http4s.md index b2b795d637..036a35a163 100644 --- a/docs/backends/http4s.md +++ b/docs/backends/http4s.md @@ -8,24 +8,13 @@ This backend is based on [http4s](https://http4s.org) (client) and is **asynchro "com.softwaremill.sttp.client3" %% "http4s-ce2-backend" % "@VERSION@" // for cats-effect 2.x & http4s 0.21.x ``` -The backend can be created in a couple of ways, e.g.: - -```scala mdoc:compile-only -import cats.effect._ -import sttp.capabilities.fs2.Fs2Streams -import sttp.client3._ -import sttp.client3.http4s._ - -Http4sBackend.usingDefaultBlazeClientBuilder[IO](): Resource[IO, SttpBackend[IO, Fs2Streams[IO]]] -``` - Sending a request is a non-blocking, lazily-evaluated operation and results in a wrapped response. There's a transitive dependency on `http4s`. There are also [other cats-effect-based backends](catseffect.md), which don't depend on http4s. Please note that: -* the backend contains an **optional** dependency on `http4s-blaze-client`, to provide the `Http4sBackend.usingBlazeClientBuilder` and `Http4sBackend.usingDefaultBlazeClientBuilder` methods. This makes the client usable with other http4s client implementations, without the need to depend on blaze. +* you have to build up your own `Client[F]` by either using _Blaze_, _Ember_ or something else * the backend does not support `SttpBackendOptions`, that is specifying proxy settings (proxies are not implemented in http4s, see [this issue](https://github.com/http4s/http4s/issues/251)), as well as configuring the connect timeout * the backend does not support the `RequestT.options.readTimeout` option diff --git a/http4s-backend/src/main/scala/sttp/client3/http4s/Http4sBackend.scala b/http4s-backend/src/main/scala/sttp/client3/http4s/Http4sBackend.scala index 6bda7e8a77..cf67077a5b 100644 --- a/http4s-backend/src/main/scala/sttp/client3/http4s/Http4sBackend.scala +++ b/http4s-backend/src/main/scala/sttp/client3/http4s/Http4sBackend.scala @@ -10,8 +10,9 @@ import fs2.io.file.Files import fs2.{Chunk, Stream} import org.http4s.{ContentCoding, EntityBody, Status, Request => Http4sRequest} import org.http4s -import org.http4s.client.Client import org.http4s.blaze.client.BlazeClientBuilder +import org.http4s.client.Client +import org.http4s.ember.client.EmberClientBuilder import org.typelevel.ci.CIString import sttp.capabilities.fs2.Fs2Streams import sttp.client3.http4s.Http4sBackend.EncodingHandler @@ -301,16 +302,13 @@ object Http4sBackend { blazeClientBuilder.resource.map(c => usingClient(c, customizeRequest, customEncodingHandler)) } - def usingDefaultBlazeClientBuilder[F[_]: Async]( - clientExecutionContext: ExecutionContext = ExecutionContext.global, + def usingEmberClientBuilder[F[_]: Async]( + emberClientBuilder: EmberClientBuilder[F], customizeRequest: Http4sRequest[F] => Http4sRequest[F] = identity[Http4sRequest[F]] _, customEncodingHandler: EncodingHandler[F] = PartialFunction.empty - ): Resource[F, SttpBackend[F, Fs2Streams[F]]] = - usingBlazeClientBuilder( - BlazeClientBuilder[F](clientExecutionContext), - customizeRequest, - customEncodingHandler - ) + ): Resource[F, SttpBackend[F, Fs2Streams[F]]] = { + emberClientBuilder.build.map(c => usingClient(c, customizeRequest, customEncodingHandler)) + } /** Create a stub backend for testing, which uses the `F` response wrapper, and supports `Stream[F, Byte]` streaming. * diff --git a/http4s-backend/src/test/scala/sttp/client3/http4s/Http4sHttpStreamingTest.scala b/http4s-backend/src/test/scala/sttp/client3/http4s/Http4sHttpStreamingTest.scala index 252b394e60..2384ff8936 100644 --- a/http4s-backend/src/test/scala/sttp/client3/http4s/Http4sHttpStreamingTest.scala +++ b/http4s-backend/src/test/scala/sttp/client3/http4s/Http4sHttpStreamingTest.scala @@ -10,8 +10,8 @@ import sttp.capabilities.fs2.Fs2Streams class Http4sHttpStreamingTest extends Fs2StreamingTest { - private val blazeClientBuilder = BlazeClientBuilder[IO](ExecutionContext.global) + private val blazeClientBuilder = BlazeClientBuilder[IO] override val backend: SttpBackend[IO, Fs2Streams[IO]] = - Http4sBackend.usingBlazeClientBuilder(blazeClientBuilder).allocated.unsafeRunSync()._1 + blazeClientBuilder.resource.map(c => Http4sBackend.usingClient(c)).allocated.unsafeRunSync()._1 } diff --git a/http4s-backend/src/test/scala/sttp/client3/http4s/Http4sHttpTest.scala b/http4s-backend/src/test/scala/sttp/client3/http4s/Http4sHttpTest.scala index f86e3d8282..06e7f7bcdf 100644 --- a/http4s-backend/src/test/scala/sttp/client3/http4s/Http4sHttpTest.scala +++ b/http4s-backend/src/test/scala/sttp/client3/http4s/Http4sHttpTest.scala @@ -9,10 +9,10 @@ import sttp.client3.testing.HttpTest import scala.concurrent.ExecutionContext class Http4sHttpTest extends HttpTest[IO] with CatsRetryTest with CatsTestBase { - private val blazeClientBuilder = BlazeClientBuilder[IO](ExecutionContext.global) + private val blazeClientBuilder = BlazeClientBuilder[IO] override val backend: SttpBackend[IO, Any] = - Http4sBackend.usingBlazeClientBuilder(blazeClientBuilder).allocated.unsafeRunSync()._1 + blazeClientBuilder.resource.map(c => Http4sBackend.usingClient(c)).allocated.unsafeRunSync()._1 override protected def supportsRequestTimeout = false override protected def supportsCustomMultipartContentType = false diff --git a/http4s-ce2-backend/src/main/scala/sttp/client3/http4s/Http4sBackend.scala b/http4s-ce2-backend/src/main/scala/sttp/client3/http4s/Http4sBackend.scala index 6e31061686..f9e5e13235 100644 --- a/http4s-ce2-backend/src/main/scala/sttp/client3/http4s/Http4sBackend.scala +++ b/http4s-ce2-backend/src/main/scala/sttp/client3/http4s/Http4sBackend.scala @@ -10,8 +10,8 @@ import cats.effect.implicits._ import fs2.{Chunk, Stream} import org.http4s.{ContentCoding, EntityBody, Status, Request => Http4sRequest} import org.http4s -import org.http4s.client.Client import org.http4s.blaze.client.BlazeClientBuilder +import org.http4s.client.Client import org.http4s.headers.`Content-Encoding` import org.typelevel.ci.CIString import sttp.capabilities.fs2.Fs2Streams @@ -302,19 +302,6 @@ object Http4sBackend { blazeClientBuilder.resource.map(c => usingClient(c, blocker, customizeRequest, customEncodingHandler)) } - def usingDefaultBlazeClientBuilder[F[_]: ConcurrentEffect: ContextShift]( - blocker: Blocker, - clientExecutionContext: ExecutionContext = ExecutionContext.global, - customizeRequest: Http4sRequest[F] => Http4sRequest[F] = identity[Http4sRequest[F]] _, - customEncodingHandler: EncodingHandler[F] = PartialFunction.empty - ): Resource[F, SttpBackend[F, Fs2Streams[F]]] = - usingBlazeClientBuilder( - BlazeClientBuilder[F](clientExecutionContext), - blocker, - customizeRequest, - customEncodingHandler - ) - /** Create a stub backend for testing, which uses the `F` response wrapper, and supports `Stream[F, Byte]` streaming. * * See [[sttp.client3.testing.SttpBackendStub]] for details on how to configure stub responses. diff --git a/http4s-ce2-backend/src/test/scala/sttp/client3/http4s/Http4sHttpStreamingTest.scala b/http4s-ce2-backend/src/test/scala/sttp/client3/http4s/Http4sHttpStreamingTest.scala index c65157956e..7f422da3d6 100644 --- a/http4s-ce2-backend/src/test/scala/sttp/client3/http4s/Http4sHttpStreamingTest.scala +++ b/http4s-ce2-backend/src/test/scala/sttp/client3/http4s/Http4sHttpStreamingTest.scala @@ -12,6 +12,6 @@ class Http4sHttpStreamingTest extends Fs2StreamingTest { private val blazeClientBuilder = BlazeClientBuilder[IO](ExecutionContext.global) override val backend: SttpBackend[IO, Fs2Streams[IO]] = - Http4sBackend.usingBlazeClientBuilder(blazeClientBuilder, blocker).allocated.unsafeRunSync()._1 + blazeClientBuilder.resource.map(c => Http4sBackend.usingClient(c, blocker)).allocated.unsafeRunSync()._1 } diff --git a/http4s-ce2-backend/src/test/scala/sttp/client3/http4s/Http4sHttpTest.scala b/http4s-ce2-backend/src/test/scala/sttp/client3/http4s/Http4sHttpTest.scala index 1026d6d909..66585346e7 100644 --- a/http4s-ce2-backend/src/test/scala/sttp/client3/http4s/Http4sHttpTest.scala +++ b/http4s-ce2-backend/src/test/scala/sttp/client3/http4s/Http4sHttpTest.scala @@ -12,7 +12,7 @@ class Http4sHttpTest extends HttpTest[IO] with CatsTestBase { private val blazeClientBuilder = BlazeClientBuilder[IO](ExecutionContext.global) override val backend: SttpBackend[IO, Any] = - Http4sBackend.usingBlazeClientBuilder(blazeClientBuilder, blocker).allocated.unsafeRunSync()._1 + blazeClientBuilder.resource.map(c => Http4sBackend.usingClient(c, blocker)).allocated.unsafeRunSync()._1 override protected def supportsRequestTimeout = false override protected def supportsCustomMultipartContentType = false