async-aws/core
Shared core library for AsyncAws services: common utilities, HTTP/stream handling, exceptions, and AWS request/response infrastructure. Includes an STS client for authentication and credentials. Install via composer require async-aws/core.
Installation:
composer require async-aws/core
Add to composer.json if using Laravel:
"require": {
"async-aws/core": "^1.29"
}
Basic Usage:
use AsyncAws\Core\AwsClientFactory;
use AsyncAws\Core\Configuration;
// Initialize with default AWS config (reads ~/.aws/credentials and ~/.aws/config)
$clientFactory = new AwsClientFactory(new Configuration());
// Get an STS client (included in core)
$stsClient = $clientFactory->sts();
First Use Case: Assume a role using STS:
$result = $stsClient->assumeRole([
'RoleArn' => 'arn:aws:iam::123456789012:role/ExampleRole',
'RoleSessionName' => 'LaravelSession'
]);
$credentials = $result->getCredentials();
AwsClientFactory: Central hub for creating AWS service clients (STS, S3, etc.).Configuration: Handles AWS config (profiles, regions, endpoints).CredentialProvider: Manages AWS credentials (IAM, SSO, environment variables).Pattern: Use AwsClientFactory with a Configuration object to standardize client creation.
// Laravel Service Provider
public function register()
{
$this->app->singleton(AwsClientFactory::class, function ($app) {
$config = new Configuration([
'region' => 'us-east-1',
'profile' => 'laravel-app',
]);
return new AwsClientFactory($config);
});
}
Workflow:
AwsClientFactory into services needing AWS clients.$s3Client = $clientFactory->s3();
$ec2Client = $clientFactory->ec2();
Pattern: Leverage built-in credential providers (IAM, SSO, environment variables).
// Use environment variables (AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY)
$config = new Configuration(['region' => 'eu-west-1']);
// Use SSO (requires async-aws/sso package)
$config = new Configuration([
'profile' => 'sso-profile',
'sso_start_url' => 'https://d-123456789.sso.us-east-1.amazonaws.com/start',
]);
Laravel-Specific:
.env:
AWS_ACCESS_KEY_ID=your_key
AWS_SECRET_ACCESS_KEY=your_secret
AWS_DEFAULT_REGION=us-east-1
config('services.aws') to pass to Configuration.Pattern: Use AwsRetryStrategy for idempotent operations (e.g., S3 uploads).
use AsyncAws\Core\Retry\AwsRetryStrategy;
$config = new Configuration([
'retry_strategy' => new AwsRetryStrategy([
'max_attempts' => 3,
'delay' => 100, // ms
]),
]);
$clientFactory = new AwsClientFactory($config);
Error Handling:
try {
$result = $s3Client->putObject([
'Bucket' => 'my-bucket',
'Key' => 'file.txt',
'Body' => fopen('local-file.txt', 'r'),
]);
} catch (\AsyncAws\Core\Exception\AwsException $e) {
// Handle AWS-specific errors (e.g., 404, 403)
logger()->error('AWS Error: ' . $e->getAwsErrorMessage());
} catch (\RuntimeException $e) {
// Handle non-AWS errors (e.g., network issues)
logger()->error('Request failed: ' . $e->getMessage());
}
Pattern: Generate presigned URLs for S3 objects (requires async-aws/s3).
$s3Client = $clientFactory->s3();
$presignedUrl = $s3Client->presign([
'Bucket' => 'my-bucket',
'Key' => 'file.txt',
'Expires' => '+1 hour',
]);
Laravel Integration:
$cache->put('presigned_url_file.txt', $presignedUrl, now()->addHour());
Pattern: Use ResultMockFactory to mock AWS responses in tests.
use AsyncAws\Core\Test\ResultMockFactory;
$mockFactory = new ResultMockFactory();
$mockResult = $mockFactory->createS3GetObjectResult([
'Body' => fopen('tests/mocks/file.txt', 'r'),
]);
// Inject mock into client (advanced: use Laravel's testing helpers)
$s3Client->setResponse($mockResult);
Laravel Testing:
MockerTrait in PHPUnit tests:
use AsyncAws\Core\Test\MockerTrait;
class MyTest extends TestCase
{
use MockerTrait;
public function testS3Upload()
{
$this->mockS3PutObject();
// Test logic...
}
}
Pattern: Handle large responses (e.g., S3 downloads) with streams.
$result = $s3Client->getObject([
'Bucket' => 'my-bucket',
'Key' => 'large-file.zip',
]);
// Stream to disk
$stream = $result->getBody();
file_put_contents('local-file.zip', $stream->getContents());
Optimization:
ResponseBodyStream for chunked downloads:
$stream = $result->getBody();
foreach ($stream as $chunk) {
// Process chunk (e.g., upload to another service)
}
~/.aws/config and ~/.aws/credentials, the package merges them automatically. Override in Configuration if needed:
$config = new Configuration([
'profile' => 'my-profile',
'region' => 'override-region', // Overrides config file
]);
@region in input objects for multi-region operations:
$stsClient->assumeRole([
'@region' => 'us-west-2',
'RoleArn' => 'arn:aws:iam::123456789012:role/ExampleRole',
]);
%region% in custom endpoints (deprecated in v2.0). Use endpoint directly:
$config = new Configuration([
'endpoint' => 'https://custom-s3-endpoint.com',
]);
async-aws/sso is installed:
composer require async-aws/sso
null to override:
$config = new Configuration([
'credentials' => [
'key' => null, // Explicitly override
'secret' => null,
],
]);
$credentialProvider = $config->getCredentialProvider();
$credentialProvider->clearCache();
GetObject, PutObject). Exclude non-retryable status codes (e.g., 400):
$config = new Configuration([
'retry_strategy' => new AwsRetryStrategy([
'retryable_status_codes' => [403, 500, 502, 503, 504],
]),
]);
Configuration:
$config = new Configuration([
'http_client_timeout' => 60, // seconds
]);
$config = new Configuration([
'debug' => true, // Logs HTTP requests/responses
]);
Logs appear in Laravel's log channel (e.g., `storage/logs/larHow can I help you explore Laravel packages today?