Aspects

It is possible to define aspects of type AwsCallAspect[R] that can modify the behavior of the AWS client modules. This can be used for example to add logging or metrics to the AWS clients and it’s also the recommended way to handle retries or apply rate limiting and other similar patterns.

To define an aspect, create an instance of the AwsCallAspect trait:

val callLogging: AwsCallAspect[Clock with Console] =
  new AwsCallAspect[Clock with Console] {
    override final def apply[R1 <: Clock with Console, A](
        f: ZIO[R1, AwsError, Described[A]]
    ): ZIO[R1, AwsError, Described[A]] = {
      f.timed.flatMap { case (duration, r @ Described(result, description)) =>
        console
          .putStrLn(
            s"[${description.service}/${description.operation}] ran for $duration"
          )
		  .ignore
          .as(r)
      }
    }
  }
// callLogging: AwsCallAspect[Clock with Console] = repl.MdocSession$App$$anon$1@7536f9c0

This aspect can attached to a client layer with the @@ operator. Multiple aspects can be composed with >>>.

To see a full example, check example #2.