Resilience covers areas such as retries, circuit breaking and rate limiting.
sttp client doesn’t have the above built-in, as these concepts are usually best handled on a higher level. Sending a request (that is, invoking
myRequest.send(backend)), can be viewed as a:
() => Response[T]function for synchronous backends
() => Future[Response[T]]for
Future-based asynchronous backends
All of these are lazily evaluated, and can be repeated. Such a representation allows to integrate the
send() side-effect with a stack-dependent resilience tool. There’s a number of libraries that implement the above mentioned resilience functionalities, hence there’s no sense for sttp client to reimplement any of those. That’s simply not the scope of this library.
Still, the input for a particular resilience model might involve both the result (either an exception, or a response) and the original description of the request being sent. E.g. retries can depend on the request method; circuit-breaking can depend on the host, to which the request is sent; same for rate limiting.
Here’s an incomplete list of libraries which can be used to manage retries in various Scala stacks:
- for ZIO: schedules, rezilience
- for Monix/cats-effect: cats-retry
- for Monix:
sttp client contains a default implementation of a predicate, which allows deciding if a request is retriable: if the body can be sent multiple times, and if the HTTP method is idempotent.
This predicate is available as
RetryWhen.Default and has type
(Request[_, _], Either[Throwable, Response[_]]) => Boolean.
Some backends have built-in retry mechanisms:
- OkHttp (see the builder’s
- async-http-client: by default, the backend will attempt 5 retries in case an
IOExceptionis thrown during the connection. This can be changed by specifying the
org.asynchttpclient.maxRequestRetryconfig option, or by providing custom configuration using when creating the backend (