Install Dependencies
composer require dbp/relay-blob-bundle dbp/relay-blob-connector-filesystem-bundle
(Replace filesystem with your preferred connector, e.g., s3, gcs.)
Configure Bundles
Add to config/bundles.php before DbpRelayCoreBundle:
Dbp\Relay\BlobBundle\DbpRelayBlobBundle::class => ['all' => true],
Configure Storage
Define buckets in config/packages/dbp_relay_blob.yaml:
dbp_relay_blob:
buckets:
default:
connector: filesystem
options:
directory: "%kernel.project_dir%/public/uploads"
First Use Case: Upload a File Use the API endpoint (auto-generated by the bundle) to upload a file:
curl -X POST \
-F "file=@/path/to/file.jpg" \
http://your-app/_relay/blob/upload?bucket=default
(Response includes an ephemeral URL for the file.)
Bucket-Based Storage
user_uploads, media_assets).buckets:
user_uploads:
connector: s3
options:
bucket: "my-app-uploads"
region: "eu-central-1"
Signed Requests for Security
minio or aws-sdk).use Dbp\Relay\BlobBundle\Service\BlobService;
$blobService = $this->container->get(BlobService::class);
$signedUrl = $blobService->generateSignedUploadUrl('default', 'file.jpg', 3600);
Integration with Laravel Controllers
use Dbp\Relay\BlobBundle\Service\BlobService;
public function upload(Request $request, BlobService $blobService) {
$file = $request->file('file');
$upload = $blobService->upload($file, 'default');
return response()->json(['url' => $upload->getUrl()]);
}
File Metadata Management
user_id, content_type) to blobs via the API.curl -X POST \
-F "file=@image.jpg" \
-F "metadata[user_id]=123" \
http://your-app/_relay/blob/upload?bucket=default
Event-Driven Extensions
blob.uploaded) to trigger post-processing (e.g., image thumbnails).// In a service provider
$this->eventDispatcher->addListener(
BlobEvents::UPLOADED,
function (BlobUploadedEvent $event) {
// Process $event->getBlob()
}
);
Connector Dependency
filesystem, s3). Forgetting to install one will throw ServiceNotFoundException.dbp/relay-blob-connector-s3-bundle).Bucket Configuration Overrides
config/packages/dbp_relay_blob.yaml are merged, not replaced. Incorrect merging can lead to silent failures.var_dump($this->container->getParameter('dbp_relay_blob.buckets')).Ephemeral URLs
403 Forbidden if not refreshed.generateSignedUploadUrl($bucket, $filename, $expirySeconds).File Size Limits
upload_max_filesize and post_max_size. Large files may fail silently.php.ini or use chunked uploads (e.g., Tus protocol via a custom connector).CORS Restrictions
$response->headers->set('Access-Control-Allow-Origin', '*');
Enable Verbose Logging
Add to config/packages/monolog.yaml:
handlers:
relay_blob:
type: stream
path: "%kernel.logs_dir%/relay_blob.log"
level: debug
channels: ["relay_blob"]
Then log events in your connector:
$this->logger->debug('Uploading file', ['bucket' => $bucket, 'file' => $file->getClientOriginalName()]);
Check Connector-Specific Errors
directory permissions (chmod -R 775 %kernel.project_dir%/public/uploads).Validate API Responses
The bundle returns JSON responses with a success flag. Always check:
{
"success": true,
"data": {
"url": "https://.../file.jpg",
"metadata": { ... }
}
}
Custom Connectors
Dbp\Relay\BlobBundle\Connector\BlobConnectorInterface and register it as a service.// src/Connector/CustomConnector.php
class CustomConnector implements BlobConnectorInterface {
public function upload(UploadedFile $file, array $options) { ... }
public function generateUrl(string $filename, array $options) { ... }
}
Middleware for Pre/Post-Processing
KernelEvents::REQUEST or BlobEvents::UPLOADED to modify requests/responses.$event->getResponse()->headers->set('X-Custom-Header', 'value');
Database Backing for Metadata
Blob entity (if using Doctrine) to add custom fields.// src/Entity/ExtendedBlob.php
class ExtendedBlob extends Blob {
/**
* @ORM\Column(type="string", nullable=true)
*/
private $customField;
}
How can I help you explore Laravel packages today?