stetodd/s3-multipart-upload-bundle
Composer 安装命令:
composer require stetodd/s3-multipart-upload-bundle
包简介
Direct-to-S3 multipart upload endpoints for Symfony (Uppy-compatible): create, sign parts, complete and abort via presigned URLs
README 文档
README
Direct-to-S3 multipart upload endpoints for Symfony, compatible with Uppy's AwsS3 multipart flow: create an upload, presign each part, then complete or abort — all against any S3-compatible store (AWS, R2, minio).
Install
composer require stetodd/s3-multipart-upload-bundle
Register in config/bundles.php:
Stetodd\S3MultipartUploadBundle\StetoddS3MultipartUploadBundle::class => ['all' => true],
Configure targets in config/packages/stetodd_s3_multipart_upload.yaml. Each target maps a client-supplied targetType to an S3 client service, bucket and key prefix:
stetodd_s3_multipart_upload: required_grant: IS_AUTHENTICATED # optional; null leaves access control to the app # presign_expiry: '+20 minutes' targets: artifact: client: app.storage.artifacts # service id of an Aws\S3\S3Client bucket: '%env(S3_BUCKET)%' base_path: 'artifact' tag: 'artifact-media' allowed_content_types: [image/jpeg, image/png, image/webp]
Import the routes with whatever prefix you like (config/routes/stetodd_s3_multipart_upload.yaml):
stetodd_s3_multipart_upload: resource: '@StetoddS3MultipartUploadBundle/config/routes.php' prefix: /s3
Endpoints
| Method | Path | Body / query | Response |
|---|---|---|---|
| OPTIONS | /create |
— | 204 |
| POST | /create |
{targetType, contentType, filename} |
{key, uploadId} |
| GET | /parts/sign |
?uploadId=&partNumber= |
{url} (presigned) |
| POST | /complete |
{uploadId, parts: [{PartNumber, ETag}]} |
{success: true}* |
| DELETE | /abort |
{uploadId} |
{} |
* listeners can replace any create/complete response — see below.
Application seams
The bundle deliberately persists nothing. Two integration points connect it to your domain:
1. Upload resolver (required for sign/complete/abort). Map an uploadId back to the object key and target you stored when the upload was created:
use Symfony\Component\DependencyInjection\Attribute\AsAlias; #[AsAlias(UploadResolverInterface::class)] final readonly class FileUploadResolver implements UploadResolverInterface { public function resolve(string $uploadId): ResolvedUpload { $upload = $this->repository->findByUploadId($uploadId) ?? throw UploadNotFoundException::forUploadId($uploadId); return new ResolvedUpload($upload->getKey(), $upload->getTargetType()); } }
Unknown ids surface as 404s.
2. Lifecycle events. Subscribe to persist your upload record and run post-completion behaviour:
MultipartUploadCreated—descriptor(filename, uploadId, key, bucket, tag) +target; persist your record here.setResponse()overrides the default{key, uploadId}body.MultipartUploadCompleted—uploadId,key,target; mark your record complete, kick off processing, and optionallysetResponse()(e.g. return the created domain resource).MultipartUploadAborted—uploadId,key,target.
Storage services
Each configured target also exposes stetodd_s3_multipart_upload.storage.<name> (a MultipartStorageInterface) with presigned GET URLs (getTemporaryUrl), part listing and ranged reads (readRange) for use elsewhere in your app, resolvable by target string via TargetStorageLocator.
统计信息
- 总下载量: 1
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 0
- 点击次数: 2
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2026-06-12