Skip to content

RFC: design suggestion: Make this a "3-tier library" #392

Open
@weissi

Description

@weissi

At the moment, we have a pretty gnarly issue with AHC's API: Settings can either be supplied globally or per request. So if you want to set certain configuration for a certain component in your app (say TLS config, redirect config, ...) then you either have to specify it for every single request (tedious) or globally (expensive as you'll get a new connection pool, need to maintain lifecycle etc).

What I suggest here is making AHC a "3-tier library":

  • tier 1: What is currently HTTPClient: the highly stateful, expensive, and lifecycle-managed object that owns the TLSContext, the connection pool, and if not .shared also the ELG
  • tier 2: (doesn't exist right now) A very lightweight (probably struct) and not lifecycle managed client object which is essentially a reference to the tier 1 object and a bag of configuration
  • tier 3: the individual requests

An API sketch could look like this:

// tier 1
let http = HTTPService(eventLoopGroupProvider: .shared(myELG)) // This is currently called `HTTPClient`
defer {
    try! http.syncShutdown()
}

// tier 2 (creating this is ~free, doesn't need to be shut down)
let httpClient = http.client(tlsConfiguration: specialConfig, redirectConfig: ...)

// tier 3
let result = httpClient.get("https://...").wait()

Benefits

  • Allows wider sharing of Tier 1 because it doesn't take configuration
  • Makes the API nicer to use because we can supply configuration to Tier 2 so we don't need to pass it to every request
  • Would allow Tier 2 to grow a "middleware" concept which would allow doing things like authenticating requests or controlling redirects etc without hard-wiring all that into the core HTTP client.

Important requirements per tier

Tier 1

  • do not take any configuration apart from the ELG

Tier 2

  • doesn't need lifecycle management
  • holds bags of configuration
  • ~free to create

Tier 3

  • can override most(all?) of the configuration set in Tier 2

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions