ClientInterface and PSR-17 factories. It depends on the interfaces rather than on a concrete client, so it uses whichever HTTP stack your project already has - and does not install a second one alongside it.
Discovery
Pass nothing andphp-http/discovery finds the implementation your project has installed:
create() raises an error naming what to install.
Injecting your own
Pass your configured client to reuse its proxy settings, middleware and instrumentation for Nexus traffic too:Any implementation works
Both are verified on every commit. One CI job installs the package into an empty project and fails if any HTTP stack comes with it; another runs the SDK end to end against Symfony HttpClient with Guzzle absent.
What gets installed
Installingwestyx/nexus brings 6 packages, about 1 MB:
Status codes
PSR-18 clients return 4xx and 5xx responses rather than throwing, and the SDK maps every status to a typed exception itself. The mapping is shared by every endpoint, so a condition reports identically wherever it occurs: a429 on an A/B evaluation carries its Retry-After and its quarantine details exactly as one on a sync does.
Response size
Every response is read with a hard byte limit enforced while reading - 10 MB for a sync, 1 MB for everything else. Exceeding it raises a size error naming the limit, rather than handing a truncated document to the JSON parser.Live updates are the exception
PSR-18’ssendRequest() returns a complete ResponseInterface, and whether the body is buffered before returning is left to the implementation. There is no standard way to request incremental delivery, so a buffering client would block forever on an endless event stream.
connectStream() therefore uses ext-curl directly, which is also what gives it a real connection deadline and a liveness deadline. Without ext-curl it raises an actionable error and everything else, TTL polling included, works normally - losing live updates is a degradation, not a failure.