alibabacloud/gateway-spi
Alibaba Cloud Gateway SPI for PHP supplies the service provider interfaces the Alibaba Cloud SDK uses to define gateway clients, requests, and responses. These contracts let SDK components and custom gateway implementations interoperate, providing a small foundational layer for building or extending...
This is not a package you install on purpose. alibabacloud/gateway-spi is a tiny interface package — the contract that Alibaba Cloud gateway implementations (most notably alibabacloud/darabonba-openapi and every generated alibabacloud/*-sdk) are written against. It ships no HTTP client, no signer, no Laravel integration.
Minimal steps:
composer show alibabacloud/gateway-spi and composer why alibabacloud/gateway-spi. In a normal Laravel app it arrives transitively the moment you composer require alibabacloud/darabonba-openapi or any generated Alibaba Cloud SDK. Requiring it directly is almost always a mistake.vendor/alibabacloud/gateway-spi/src/ — the Client interface (request/response modification, signer selection, config access) and its companions AttributeMap and Interceptor.vendor/alibabacloud/darabonba-openapi/src/OpenApiClient.php. That's the class that actually does something interesting; the SPI is just the shape it must conform to.Interceptor so every Alibaba Cloud call your Laravel app makes gets a correlation ID, tenant header, or timing log. That's the one thing this contract genuinely buys you day-to-day.There is no service provider to register. Wire it yourself in AppServiceProvider (or a dedicated AlibabaCloudServiceProvider).
Type-hint the interface, build the concrete class. Bind a factory in your container that returns an OpenApiClient (or your own implementation) as AlibabaCloud\Gateway\Spi\Client. Controllers and jobs then depend on the interface and stay testable.
$this->app->singleton(Client::class, fn ($app) => new OpenApiClient(
$app['config']->get('services.alicloud')
));
Interceptor as the primary extension seam. Implement Interceptor, keep it stateless, and register it on the gateway config for cross-cutting concerns: request IDs, tenant/X-Env tags, metrics, structured request logging. This is the Laravel-middleware analogue and it's where 90% of real-world usage of this package lands.
Treat AttributeMap as a mutable request bag. It carries the request, runtime options, and headers through the pipeline. Read from it in interceptors; mutate only the keys you own (headers, runtime options). If you need to pass data between interceptors, that's the place — but namespace your keys.
Custom Client implementation for non-Alibaba endpoints. If you need Alibaba-style signing against an internal service, implement the SPI, delegate signing to your own signer, and plug it in via your service provider. Keep the class thin — it should be an adapter over your own domain code, not the place where business logic lives.
Testing. Because the SPI is an interface, fake it: bind a stub Client in the container and assert the AttributeMap your interceptors produce. For end-to-end tests, the underlying runtime uses Guzzle — bind a MockHandler into the handler stack rather than trying to Http::fake() (Laravel's HTTP client is not in this path).
Config plumbing. Put credentials, endpoint, and the interceptor list in config/services.php under an alicloud key. Build the gateway once, in a singleton. Never new OpenApiClient(...) inside a controller or job.
gateway-spi + darabonba-openapi + each generated SDK) together in composer.json; a mismatched set is the most common source of "class does not implement interface" fatals.Client yourself, a future minor bump to the SPI can add a method and break you at runtime. Isolate your implementation behind your own adapter class so the blast radius is one file.AttributeMap. When debugging, dump the map in a deliberately-first interceptor and compare against what the signer sees.GuzzleHttp\Exception\* or Illuminate\Http\Client\RequestException. Catch the SDK's exception hierarchy explicitly; a generic catch (\Exception) here will swallow signing errors you actually want to see.config:cache. Prefer the SDK's credential providers (env, STS, instance role) over hardcoded keys. Rotating keys in .env requires php artisan config:clear on cached deployments — a classic "it worked locally" trap.getSigner()/getConfig() on the gateway are the seam for swapping signing and transport config; the interceptor list is the seam for observability. Don't mix them.Http::withHeaders(...) with HMAC signing you control. This package only earns its keep when you're already inside the generated-SDK ecosystem or you specifically need a spec-compliant, swappable gateway abstraction.How can I help you explore Laravel packages today?