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

Tea Laravel Package

alibabacloud/tea

Tea is the core PHP runtime underpinning Alibaba Cloud SDKs, providing request/response abstractions, HTTP transport, retries, and error handling. Use it as a dependency when building or customizing Alibaba Cloud API clients rather than for standalone features.

View on GitHub
Deep Wiki
Context7

Getting Started

alibabacloud/tea is not a client library you call for a specific service — it's the runtime layer that every Alibaba Cloud "Darabonba/Tea"-generated SDK (alibabacloud/ecs-20140526, alibabacloud/oss-*, alibabacloud/dysmsapi-*, …) sits on top of. If you have any Alibaba SDK installed, you already have it.

Step 1 — confirm it's there and see who pulled it in

composer show alibabacloud/tea        # version in your tree
composer why alibabacloud/tea         # which SDK(s) require it

Installing it standalone is only useful when you want to hand-roll HTTP calls against an endpoint that has no generated SDK.

composer require alibabacloud/tea alibabacloud/tea-utils

Step 2 — read four files, ignore the rest

File Why you care
vendor/alibabacloud/tea/src/Tea.php The static facade: request(), merge(), is4xx(), is5xx(), sleep(). The retry loop lives here.
src/Request.php Mutable value object: protocol, method, pathname, headers, query, body, port. Everything you can influence goes through this.
src/Response.php getStatusCode(), getHeaders(), getBody(), getStatusMessage().
src/Exception/TeaError.php, TeaUnableRetryError.php The two exceptions you will actually catch. TeaError carries a data array, not just a message.

Note the namespace is AlibabaCloud\Tea, not Tea — use Tea\Tea; will fail to autoload.

Step 3 — first use case: fire a request by hand

The minimum viable call is building a Request and handing it to Tea::request().

use AlibabaCloud\Tea\Request;
use AlibabaCloud\Tea\Tea;
use AlibabaCloud\Tea\Utils\Utils\RuntimeOptions; // from alibabacloud/tea-utils

$request = new Request();
$request->setProtocol('https');
$request->setMethod('GET');
$request->setPathname('/v1/status');
$request->setHeaders([
    'host'   => 'api.example.com',   // required: curl routes on this, not on the URL
    'accept' => 'application/json',
]);
$request->setQuery(['page' => '1']);
$request->setBody(null);

$runtime  = new RuntimeOptions(['connectTimeout' => 3000, 'readTimeout' => 5000]);
$response = Tea::request($request, $runtime);

$payload = json_decode($response->getBody(), true);

If that works, you understand 80% of the package. Everything else in the ecosystem is generated code that builds exactly this structure.

Method names have shifted across 0.1.x → 0.2.x releases. When in doubt, grep -n 'function ' vendor/alibabacloud/tea/src/Tea.php before writing against it — faster than reading the docs, which are essentially nonexistent.

Implementation Patterns

Pattern A — the 95% case: never touch the core directly. Generated clients already wrap Tea::request() with signing, endpoint resolution, and retry. Your job is only to supply RuntimeOptions and read $response->body:

$runtime = new RuntimeOptions([
    'autoretry'      => true,
    'maxAttempts'    => 3,
    'connectTimeout' => 5000,
    'readTimeout'    => 10000,
]);
$response = $client->describeInstancesWithOptions($request, $runtime);

Reach for the core only when a generated SDK's defaults are wrong.

Pattern B — a custom client for a non-Alibaba API. The real value of this package outside Alibaba is that Request/Response are plain, serializable objects. Use them as your transport abstraction so the rest of your code is transport-agnostic:

final class MyApiDriver
{
    public function __construct(private RuntimeOptions $runtime) {}

    public function call(string $method, string $path, array $query = [], $body = null): array
    {
        $request = new Request();
        $request->setProtocol('https');
        $request->setMethod($method);
        $request->setPathname($path);
        $request->setHeaders(['host' => 'api.example.com', 'content-type' => 'application/json']);
        $request->setQuery($query);
        $request->setBody($body === null ? null : json_encode($body));

        return json_decode(Tea::request($request, $this->runtime)->getBody(), true) ?? [];
    }
}

Pattern C — configuration layering with Tea::merge(). Generated clients merge their construction-time config with per-call options via Tea::merge($a, $b). If you write a wrapper client, use the same idiom so callers can override timeouts, endpoint, or protocol per request without you writing a withX() for each field.

Pattern D — let the runtime retry, don't hand-roll it. RuntimeOptions::$autoretry + maxAttempts drives an exponential-backoff loop inside Tea::request(). Wrapping that in your own for ($i = 0; $i < 3; $i++) produces multiplicative retries (9 attempts from 3×3) and duplicate side effects on non-idempotent POSTs. Set autoretry only on idempotent calls.

Pattern E — structured error handling. Parse TeaError for the fields you actually need for logs and support tickets:

try {
    $response = $client->sendMessageWithOptions($request, $runtime);
} catch (TeaError $e) {
    $data = $e->getData(); // ['code'=>..., 'message'=>..., 'requestId'=>..., 'httpCode'=>...]
    Log::warning('aliyun api error', $data + ['operation' => 'SendMessage']);
    throw new ApiException($data['message'] ?? $e->getMessage(), $data['httpCode'] ?? 0);
} catch (TeaUnableRetryError $e) {
    // all attempts exhausted — the useful detail is on the inner exception
    report($e->getLastException() ?? $e);
}

Pattern F — test request construction without the network. Because Request is just a settable object, assert on getPathname(), getQuery(), getHeaders() and getBody() directly. Only integration-test against a real endpoint. This is the cheapest test layer available in the whole Alibaba SDK stack.

Pattern G — cross-cutting headers. Correlation IDs, tenant tags, and proxy headers can be injected onto $request->getHeaders() before handing it to Tea::request(). This works because signing happens upstream in the SDK's doRequest(). See the pitfall below.

Gotchas and Tips

  • Never mutate headers after signing. Alibaba requests are signed over the canonicalized header set (x-acs-*, host, content-type). If you inject a header after the SDK has signed, you get a SignatureDoesNotMatch that looks like a credential problem but isn't. Inject before signing, or restrict yourself to unsigned headers.

  • host header is mandatory on hand-built requests. Tea::request() goes through curl and routes on the header, not on a parsed URL — omit it and you get a confusing DNS/connection error.

  • The license is NOASSERTION on Packagist. Read vendor/alibabacloud/tea/LICENSE before shipping this in a distributed product. It's almost certainly Apache-2.0 like the rest of the ecosystem, but do the two-minute check rather than guessing from the metadata.

  • "Dependents: 0" is a Packagist artifact, not reality. Hundreds of alibabacloud/* packages require it transitively. Judge the package by the generated SDKs consuming it, not by its own star count — 7 stars is simply because nobody requires the transport layer on purpose.

  • Stale-looking releases are normal here. Last release 2023-05-16 with a 5.6-era PHP constraint in composer.json means it installs on almost anything — that is not evidence it's tested on PHP 8.3. Run your integration tests on your actual target version, especially around curl handle cleanup and byte-string handling.

  • Composer conflict magnet. Different generated SDKs pin alibabacloud/tea to different ~0.x minors. When composer require explodes, composer why alibabacloud/tea and composer update --with-dependencies alibabacloud/tea usually resolves it; downgrading the newest SDK is the fallback.

  • Tea::sleep() takes milliseconds. The rest of PHP sleeps in seconds. A Tea::sleep(5) "delay" is a 5 ms no-op.

  • Tea::is4xx() / Tea::is5xx() take a Response, not an int. Passing $response->getStatusCode() returns a truthy garbage result rather than erroring.

  • getBody() is not guaranteed to be a clean JSON string. Error responses may be empty, XML, or an HTML gateway page. Always guard: $data = json_decode($response->getBody() ?? '', true); if (!is_array($data)) { ... }.

  • Header arrays are case-sensitive in PHP, even though HTTP isn't. Reading $response->getHeaders()['content-type'] when the wire sent Content-Type yields null. Look up case-insensitively in any wrapper you write.

  • ignoreSSL exists but should never reach production. It's for local proxies and self-signed test endpoints only. Lint for it in review.

  • Console::log() writes to stdout/STDERR. Fine in a CLI worker, silently corrupts JSON responses in FPM. Route logs through your framework's logger instead.

  • TeaUnableRetryError is a wrapper. Its message is generic ("Retry failed"); the actionable exception and response are on the inner accessors. Catching it and logging getMessage() alone makes retry failures undebuggable.

  • Extension point worth knowing: the retry/backoff policy is entirely driven by the runtime bag you pass in — core doesn't hold global state. That means you can safely run two clients with different timeout/retry profiles in the same process, which is the cleanest way to isolate a flaky dependency.

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.
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource