Skip to main content
The PHP SDK talks to Nexus through a PSR-18 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 and php-http/discovery finds the implementation your project has installed:
If there is none, 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:
Each part falls back to discovery independently, so supplying only the client is fine. In Laravel this happens for you - the service provider takes the container’s PSR-18 binding when there is one.

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

Installing westyx/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.
If you previously wrapped SDK calls in Guzzle-specific error handling, GuzzleHttp\Exception\* no longer reaches your code from the SDK. Catch WestyxNexus\Exceptions\NexusException and its subclasses instead - see Error handling.
The mapping is shared by every endpoint, so a condition reports identically wherever it occurs: a 429 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’s sendRequest() 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.