sttp icon indicating copy to clipboard operation
sttp copied to clipboard

A PoC of Gears integration

Open adamw opened this issue 1 year ago • 0 comments
trafficstars

See https://github.com/lampepfl/gears

Currently sttp-client defines a couple of backend types: SyncBackend, Backend[F[_]], WebSocketSyncBackend, StreamBackend[F[_], +S], WebSocketStreamBackend[F[_], S].

They all inherit from a GenericBackend[F[_], +P] (where P are supported sttp-capabilities, such as streaming and websockets), but sttp has specialisied "concrete" types for better auto-complete and general developer experience.

My first first thought was to add a CapabilityBackend[C] to the hierarchy, but this would mean also adding a WebSocket/Streaming variants, and adding the new variants for all generic backend wrappers. This would additionally complicate the already complicated setup.

So instead, I went with representing the "Gears effect" as a type constructor (I called it Deferred), and using Backend[F[_]]:

One thing that is not ideal is the .send variant that I had to add, which would work for any capability:

def send[C](backend: Backend[[X] =>> C ?=> X])(using C): Response[T] = backend.send(this)

This is needed so that both of these compile:

val result: Response[Either[String, String]] = basicRequest.get(uri"https://x.org/").body("123").send(b)
val result = basicRequest.get(uri"https://x.org/").body("123").send(b)

(without it only the second, not-explicitly-typed one compiles)

I also tried adding a gears-specific extension method (which would have a using Async, instead of the generic formulation above), but unfortunately the .send methods defined directly in the Request class have priority, so this method was never taken into consideration.

Anyway, summing up, to add gears integration into sttp-client with the approach above, we have to:

  • add a capability-generic .send variant
  • in the gears integration, create a type alias which allows representing a capability-aware computation as an effect
  • define the backend, either wrapping a synchronous backend, or implementing custom logic using the capability

adamw avatar Apr 20 '24 12:04 adamw