Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Openapi Core Laravel Package

alibabacloud/openapi-core

The core runtime for Alibaba Cloud PHP SDK clients, handling request signing, credential and endpoint resolution, retries, timeouts, error parsing, and gateway communication so generated OpenAPI clients can call Alibaba Cloud services reliably.

View on GitHub
Deep Wiki
Context7

Getting Started

Understand what you're installing. alibabacloud/openapi-core is not a product SDK. It is the framework-agnostic runtime layer that every generated Alibaba Cloud PHP SDK sits on top of (alibabacloud/ecs-20140526, alibabacloud/oss-*, alibabacloud/slb-*, etc.). Its classes live under AlibabaCloud\SDK\OpenapiCore\, and it pulls in alibabacloud/darabonba-openapi, which is where the day-to-day models you actually type (Config, Params, RuntimeOptions) come from — namespace Darabonba\OpenApi\Models\.

That explains the "0 dependents": Composer dependency counts only see this package, not the several hundred product SDKs that require it transitively. You will almost never composer require alibabacloud/openapi-core directly. You get it as a side effect of installing a product SDK, or you install it deliberately when you need the generic gateway API (a product Alibaba Cloud does not publish an SDK for, or an older API version).

Where to look first. Within vendor/alibabacloud/openapi-core/src, open AlibabaCloud.php (the static entry point), OpenApiClient.php (the instance entry point), and Models/Params.php + Models/RuntimeOptions.php — those two models define almost every knob you will ever touch. Then read the README of the product SDK you installed; that is where action, version, style, and bodyType values for your specific API come from.

Minimal setup in a Laravel app.

composer require alibabacloud/openapi-core
// config/services.php
'alibaba_cloud' => [
    'access_key_id'     => env('ALIBABA_CLOUD_ACCESS_KEY_ID'),
    'access_key_secret' => env('ALIBABA_CLOUD_ACCESS_KEY_SECRET'),
    'region'            => env('ALIBABA_CLOUD_REGION', 'cn-hangzhou'),
],

First use case: the generic call, for an API with no published SDK.

use AlibabaCloud\SDK\OpenapiCore\AlibabaCloud;
use Darabonba\OpenApi\Models\Config;
use Darabonba\OpenApi\Models\Params;
use Darabonba\OpenApi\Models\RuntimeOptions;

$config = new Config([
    'accessKeyId'     => config('services.alibaba_cloud.access_key_id'),
    'accessKeySecret' => config('services.alibaba_cloud.access_key_secret'),
    'endpoint'        => 'ecs.cn-hangzhou.aliyuncs.com',
]);

$params = new Params([
    'action'      => 'DescribeInstances',
    'version'     => '2014-05-26',
    'protocol'    => 'HTTPS',
    'pathname'    => '/',
    'method'      => 'POST',
    'authType'    => 'AK',
    'style'       => 'RPC',       // RPC | ROA
    'reqBodyType' => 'formData',  // formData | json | byte | stream
    'bodyType'    => 'json',      // json | byte | stream | string
]);

$result = AlibabaCloud::callApi($params, $config, new RuntimeOptions([
    'connectTimeout' => 3000,
    'readTimeout'    => 10000,
]));

// $result is a Tea model: $result->body, $result->headers, $result->statusCode

If you have a product SDK, skip all of the above and use its typed client — new Ecs(new Config([...])), then $client->describeInstances($request). Same underlying package, far better DX.

Implementation Patterns

Bind one client as a singleton, not per-controller. Config and the client object are cheap but the underlying Guzzle handler stack and credential provider chain are not free. Register a scoped/singleton binding in a service provider and inject an interface you own:

// app/Providers/AlibabaCloudServiceProvider.php
$this->app->singleton(CloudClient::class, function () {
    $config = new Config([
        'accessKeyId'     => config('services.alibaba_cloud.access_key_id'),
        'accessKeySecret' => config('services.alibaba_cloud.access_key_secret'),
        'endpoint'        => 'ecs.'.config('services.alibaba_cloud.region').'.aliyuncs.com',
        'connectTimeout'  => 3000,
        'readTimeout'     => 10000,
    ]);

    return new CloudClient(new Ecs($config));
});

Wrap it behind your own interface. You want interface CloudClient { public function listInstances(): array; } with an implementation that calls AlibabaCloud::callApi(). This is the single most valuable pattern here: it gives you something to fake in tests, it lets you swap the raw SDK response for a DTO, and it stops Tea\Exception\TeaError leaking into your HTTP layer.

Pick a credential strategy explicitly, per environment.

Environment Credential
Local / CI Access key from .env
ECS / ACK ECS RAM role (EcsRamRoleCredentialProvider) — no secrets at all
Cross-account RamRoleArnCredentialProvider (STS AssumeRole)
Customer-facing BearerTokenCredentialProvider for OAuth-protected endpoints

For anything running on Alibaba Cloud infrastructure, prefer the RAM role and set Config.credential rather than passing keys. That removes the secret from your .env, your config cache, and your logs.

Use RuntimeOptions for retries, not Config. Auto-retry belongs on the call, so you can apply a different policy to a read (Describe*, retry freely) than to a write (Create*, retry with idempotency tokens only):

$runtime = new RuntimeOptions([
    'autoretry'      => true,
    'maxAttempts'    => 3,
    'connectTimeout' => 2000,
    'readTimeout'    => 15000,
    'proxy'          => config('services.alibaba_cloud.proxy'), // null in prod
]);

Push calls into queued jobs. These are 100ms–3s network round trips to a region that may be far away. A request–response cycle is the wrong place for RunInstances. Encode the intent in the job, let the job own the retry policy, and expose status through your own model.

Log at the boundary, once. Because the SDK does its own signing and body serialization, debugging is much easier if you capture $params->action, the endpoint, the requestId from the error body, and the HTTP status in one structured log line. Do not log Config — it contains the access key secret in plaintext.

For multi-region work, create one client per region and key them in a map. Config.endpoint is fixed at construction; there is no per-call region override.

Gotchas and Tips

  • Config silently ignores unknown keys. A typo like 'access_key_id' instead of 'accessKeyId' produces an empty credential and a confusing InvalidAccessKeyId.NotFound at call time rather than a config error. Validate the four required keys at boot; do not trust the constructor.
  • Timeouts default to effectively infinite. Always set connectTimeout and readTimeout explicitly. This is the single most common cause of hung queue workers with this package.
  • Two different exception families. SDK-level API errors arrive as Tea\Exception\TeaError (inspect $e->code, $e->data['RequestId'] for support tickets). Transport failures bubble out as GuzzleHttp\Exception\ConnectException / RequestException. Catch \Throwable at your wrapper boundary and normalize.
  • Throttling and ServiceUnavailable are expected, not exceptional. Alibaba Cloud rate-limits per API action. Honor the Retry-After-ish semantics with exponential backoff; do not let autoretry be your only defence on high-volume jobs.
  • reqBodyType / bodyType / style must match the API's documentation exactly. Getting style: RPC on an ROA API, or bodyType: json where byte is required, yields IncompleteSignature or InvalidParameter that looks like a credentials problem but isn't.
  • Guzzle version pinning. The package accepts Guzzle 6 or 7; modern Laravel requires 7. If you are on an old Laravel that pins Guzzle 6, you can get a dependency resolution wall. Also watch guzzlehttp/psr7 — it is the usual conflict when two vendor SDKs disagree.
  • Pin the minor version. Releases are frequent and near-automated (the current one is dated in the future — a sign of scheduled CI publishing). "alibabacloud/openapi-core": "~0.x.0" inside a lockfile you commit is fine; a floating * is not, because a generator change can alter Params defaults under you.
  • No test double exists. There is no Http::fake() equivalent — the client builds its own handler stack. Faking means either (a) mocking your own interface, which is why the wrapper pattern matters, or (b) injecting a Guzzle MockHandler through RuntimeOptions['handler'] if that release supports it. Option (a) is the only one I would rely on.
  • Octane / long-lived workers. The client is stateless enough to reuse, but STS-based credential providers cache tokens internally and expire. If you see intermittent SecurityTokenExpired after a worker has been up for hours, you are holding a client past its token refresh window — resolve it scoped per request instead of singleton.
  • ignoreSSL and proxy are your local-dev escape hatches. Reach for them only behind an explicit app()->isLocal() guard; they exist for debugging through Charles/mitmproxy and nothing else.
  • Extension point: when you need observability (metrics per action, request tracing), the place to add it is your own wrapper, not middleware inside the SDK. Treat the SDK as a transport and keep all cross-cutting concerns on your side of the interface.
  • Don't fight the generated types. Product SDK *Request classes are generated and regenerated. If you need extra behaviour, subclass your own DTO around the response rather than modifying anything in vendor/.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
skyraptor/chatter
edlugz/sasapay
abbasudo/artisan-route
mirvan/ippanel
ignibyte/aic-framework
glavweb/data-schema-bundle
glavweb/datagrid-bundle
tacticmedia/scim-server
uni-method/frame
neika-ai/sdk
adachsoft/php-code-style
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
adachsoft/api-version-bundle
cgv/localized-resource