BracketRequestResponse

org.http4s.server.middleware.BracketRequestResponse

Middlewares which allow for bracketing on a Request/Response, including the completion of the Response body stream.

These are analogous to cats.effect.Bracket and fs2.Stream.bracket. The reason that they exist is because due to the full termination of a Response being a function of the termination of the fs2.Stream which backs the response body, you can't actually use either cats.effect.Bracket or fs2.Stream.bracket directly.

Attributes

Source
BracketRequestResponse.scala
Graph
Supertypes
class Object
trait Matchable
class Any
Self type

Members list

Type members

Types

type FullContextMiddleware[F[_], A, B] = (Kleisli[[_] =>> OptionT[F, _$2], ContextRequest[F, A], ContextResponse[F, B]]) => Kleisli[[_] =>> OptionT[F, _$3], Request[F], Response[F]]

A Middleware which uses both a ContextRequest and ContextResponse.

A Middleware which uses both a ContextRequest and ContextResponse.

Attributes

Source
BracketRequestResponse.scala

Value members

Concrete methods

def bracketRequestResponseApp[F[_], A](acquire: F[A])(release: A => F[Unit])(implicit F: MonadCancelThrow[F]): (Kleisli[F, ContextRequest[F, A], Response[F]]) => Kleisli[F, Request[F], Response[F]]

As bracketRequestResponseCaseApp, but release is simplified, ignoring the exit condition.

As bracketRequestResponseCaseApp, but release is simplified, ignoring the exit condition.

Attributes

Note

The bracketing semantics defined here differ in one very important way from cats-effect or fs2 bracketing semantics. If the Response body is not evaluated after the application of the middleware, then the release handler will not run, effectively creating a resource leak. This can happen due to a bug in a server implementation, where it fails to drain the body, or due to a user code if the Response body stream (or the Response itself) is discarded after the application of this middleware. Unfortunately, there is currently no way to avoid this. For this reason, it is strongly recommended that this middleware be applied at the most outer scope possible. Appending to or transforming the Response body is safe to do after the application of this middleware.

Source
BracketRequestResponse.scala
def bracketRequestResponseAppR[F[_], A](resource: Resource[F, A])(implicit F: MonadCancelThrow[F]): (Kleisli[F, ContextRequest[F, A], Response[F]]) => Kleisli[F, Request[F], Response[F]]

As bracketRequestResponseApp, but acquire and release are defined in terms of a cats.effect.Resource.

As bracketRequestResponseApp, but acquire and release are defined in terms of a cats.effect.Resource.

Attributes

Note

The bracketing semantics defined here differ in one very important way from cats-effect or fs2 bracketing semantics. If the Response body is not evaluated after the application of the middleware, then the release handler will not run, effectively creating a resource leak. This can happen due to a bug in a server implementation, where it fails to drain the body, or due to a user code if the Response body stream (or the Response itself) is discarded after the application of this middleware. Unfortunately, there is currently no way to avoid this. For this reason, it is strongly recommended that this middleware be applied at the most outer scope possible. Appending to or transforming the Response body is safe to do after the application of this middleware.

Source
BracketRequestResponse.scala
def bracketRequestResponseCaseApp[F[_], A](acquire: F[A])(release: (A, Outcome[F, Throwable, Unit]) => F[Unit])(implicit F: MonadCancelThrow[F]): (Kleisli[F, ContextRequest[F, A], Response[F]]) => Kleisli[F, Request[F], Response[F]]

As bracketRequestResponseCaseRoutes but defined for HttpApp, rather than HttpRoutes.

As bracketRequestResponseCaseRoutes but defined for HttpApp, rather than HttpRoutes.

Attributes

Note

The bracketing semantics defined here differ in one very important way from cats-effect or fs2 bracketing semantics. If the Response body is not evaluated after the application of the middleware, then the release handler will not run, effectively creating a resource leak. This can happen due to a bug in a server implementation, where it fails to drain the body, or due to a user code if the Response body stream (or the Response itself) is discarded after the application of this middleware. Unfortunately, there is currently no way to avoid this. For this reason, it is strongly recommended that this middleware be applied at the most outer scope possible. Appending to or transforming the Response body is safe to do after the application of this middleware.

Source
BracketRequestResponse.scala
def bracketRequestResponseCaseRoutes[F[_], A](acquire: F[A])(release: (A, Outcome[F, Throwable, Unit]) => F[Unit])(implicit F: MonadCancelThrow[F]): F => A

Bracket on the start of a request and the completion of processing the response body Stream.

Bracket on the start of a request and the completion of processing the response body Stream.

Value parameters

acquire

Effect to run each time a request is received. The result of it is put into a ContextRequest and passed to the underlying routes.

release

Effect to run at the termination of each response body, or on any error after acquire has run. Will always be called exactly once if acquire is invoked, for each request/response.

Attributes

Note

The bracketing semantics defined here differ in one very important way from cats-effect or fs2 bracketing semantics. If the Response body is not evaluated after the application of the middleware, then the release handler will not run, effectively creating a resource leak. This can happen due to a bug in a server implementation, where it fails to drain the body, or due to a user code if the Response body stream (or the Response itself) is discarded after the application of this middleware. Unfortunately, there is currently no way to avoid this. For this reason, it is strongly recommended that this middleware be applied at the most outer scope possible. Appending to or transforming the Response body is safe to do after the application of this middleware.

A careful reader might be wondering where the analogous use parameter from cats.effect.Bracket has gone. The use of the acquired resource is running the request, thus the use function is actually just the normal context route function from http4s Kleisli[OptionT[F, *], ContextRequest[F, A], Response[F]].

Source
BracketRequestResponse.scala
def bracketRequestResponseCaseRoutes_[F[_], A, B](acquire: (Request[F]) => F[ContextRequest[F, A]])(release: (A, Option[B], Outcome[F, Throwable, Unit]) => F[Unit])(implicit F: MonadCancelThrow[F]): (F, A) => B

Bracket on the start of a request and the completion of processing the response body Stream.

Bracket on the start of a request and the completion of processing the response body Stream.

This middleware uses a context on both the Request and Response. This is the most general possible encoding for bracketing on a Request/Response interaction. It is required to express certain types of bracketing use cases (see Metrics), but for most cases it is more general than is needed. Before attempting to use this middleware, you should consider if bracketRequestResponseRoutes or bracketRequestResponseCaseRoutes will work for your use case.

Value parameters

acquire

Function of the Request to a F[ContextRequest] to run each time a new Request is received.

release

Function to run on the termination of a Request/Response interaction, in all cases. The first argument is the request context, which is guaranteed to exist if acquire succeeds. The second argument is the response context, which will only exist if the generation of the ContextResponse is successful. The third argument is the exit condition, either completed, canceled, or error.

Attributes

Note

The bracketing semantics defined here differ in one very important way from cats-effect or fs2 bracketing semantics. If the Response body is not evaluated after the application of the middleware, then the release handler will not run, effectively creating a resource leak. This can happen due to a bug in a server implementation, where it fails to drain the body, or due to a user code if the Response body stream (or the Response itself) is discarded after the application of this middleware. Unfortunately, there is currently no way to avoid this. For this reason, it is strongly recommended that this middleware be applied at the most outer scope possible. Appending to or transforming the Response body is safe to do after the application of this middleware.

For some use cases, you might want to differentiate between each of the three exit branches where release may be invoked. The three exit branches are, running a Request and receiving OptionT.none[F, Response[F]], running a Request and encountering an error or cancellation before the Response is generated, or at the full consumption of the Response body stream (regardless of the ExitCase). One may determine the in which branch release is being invoked by inspecting the ExitCase and the Option[B] response context. If the response context is defined, e.g. Some(_: B), then you can be certain that the release function was executed at the termination of the body stream. This is because the response context is only (and always) present if the Response value was generated successfully (whether or not the body stream fails). If the ExitCase is Completed and the response context is None, then that means that the underlying HttpRoutes did not yield a Response, e.g. we got OptionT.none: OptionT[F, Response[F]]. Otherwise, if the ExitCase is either Error(_: Throwable) or Canceled, and the response context is None, then release is executed in response to an error or cancellation during the generation of the Response value proper, e.g. when running the underlying HttpRoutes.

A careful reader might be wondering where the analogous use parameter from cats.effect.Bracket has gone. The use of the acquired resource is running the request, thus the use function is actually just the normal context route function from http4s Kleisli[OptionT[F, *], ContextRequest[F, A], Response[F]].

Source
BracketRequestResponse.scala
def bracketRequestResponseRoutes[F[_], A](acquire: F[A])(release: A => F[Unit])(implicit F: MonadCancelThrow[F]): F => A

As bracketRequestResponseCaseRoutes, but release is simplified, ignoring the exit condition.

As bracketRequestResponseCaseRoutes, but release is simplified, ignoring the exit condition.

Attributes

Note

The bracketing semantics defined here differ in one very important way from cats-effect or fs2 bracketing semantics. If the Response body is not evaluated after the application of the middleware, then the release handler will not run, effectively creating a resource leak. This can happen due to a bug in a server implementation, where it fails to drain the body, or due to a user code if the Response body stream (or the Response itself) is discarded after the application of this middleware. Unfortunately, there is currently no way to avoid this. For this reason, it is strongly recommended that this middleware be applied at the most outer scope possible. Appending to or transforming the Response body is safe to do after the application of this middleware.

Source
BracketRequestResponse.scala
def bracketRequestResponseRoutesR[F[_], A](resource: Resource[F, A])(implicit F: MonadCancelThrow[F]): F => A

As bracketRequestResponseRoutes, but acquire and release are defined in terms of a cats.effect.Resource.

As bracketRequestResponseRoutes, but acquire and release are defined in terms of a cats.effect.Resource.

Attributes

Note

The bracketing semantics defined here differ in one very important way from cats-effect or fs2 bracketing semantics. If the Response body is not evaluated after the application of the middleware, then the release handler will not run, effectively creating a resource leak. This can happen due to a bug in a server implementation, where it fails to drain the body, or due to a user code if the Response body stream (or the Response itself) is discarded after the application of this middleware. Unfortunately, there is currently no way to avoid this. For this reason, it is strongly recommended that this middleware be applied at the most outer scope possible. Appending to or transforming the Response body is safe to do after the application of this middleware.

Source
BracketRequestResponse.scala