File Uploading di API Platform
API Platform mendukung proses unggah file seperti gambar, PDF, atau dokumen lain. Untuk itu, kita akan mengkombinasikan ApiResource, VichUploaderBundle, dan sedikit konfigurasi pada DTO agar prosesnya berjalan lancar.
1. Install Dependensi
Instal paket pendukung:
composer require vich/uploader-bundle
composer require symfony/http-foundation
Aktifkan bundle jika belum otomatis:
// config/bundles.php
return [
Vich\UploaderBundle\VichUploaderBundle::class => ['all' => true],
];
2. Konfigurasi VichUploaderBundle
# config/packages/vich_uploader.yaml
vich_uploader:
db_driver: orm
mappings:
media_object:
uri_prefix: /uploads/files
upload_destination: '%kernel.project_dir%/public/uploads/files'
3. Buat Entity MediaObject
namespace App\Entity;
use ApiPlatform\Metadata\ApiResource;
use ApiPlatform\Metadata\Post;
use ApiPlatform\Metadata\Get;
use App\Controller\UploadFileAction;
use Vich\UploaderBundle\Mapping\Annotation as Vich;
use Symfony\Component\HttpFoundation\File\File;
use Symfony\Component\Serializer\Annotation\Groups;
use Doctrine\ORM\Mapping as ORM;
#[ORM\Entity]
#[Vich\Uploadable]
#[ApiResource(
normalizationContext: ['groups' => ['media:read']],
operations: [
new Get(),
new Post(
controller: UploadFileAction::class,
deserialize: false,
openapiContext: [
'requestBody' => [
'content' => [
'multipart/form-data' => [
'schema' => [
'type' => 'object',
'properties' => [
'file' => [
'type' => 'string',
'format' => 'binary',
],
],
],
],
],
],
]
)
]
)]
class MediaObject
{
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column(type: 'integer')]
#[Groups(['media:read'])]
private ?int $id = null;
#[Vich\UploadableField(mapping: 'media_object', fileNameProperty: 'filePath')]
private ?File $file = null;
#[ORM\Column(nullable: true)]
#[Groups(['media:read'])]
private ?string $filePath = null;
#[ORM\Column(nullable: true)]
private ?\DateTimeInterface $updatedAt = null;
public function setFile(?File $file = null): void
{
$this->file = $file;
if (null !== $file) {
$this->updatedAt = new \DateTimeImmutable();
}
}
public function getFile(): ?File
{
return $this->file;
}
public function getFilePath(): ?string
{
return $this->filePath;
}
public function setFilePath(?string $filePath): void
{
$this->filePath = $filePath;
}
public function getId(): ?int
{
return $this->id;
}
}
4. Buat Controller UploadFileAction
namespace App\Controller;
use App\Entity\MediaObject;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Attribute\AsController;
use Symfony\Component\Validator\Validator\ValidatorInterface;
use Doctrine\ORM\EntityManagerInterface;
#[AsController]
class UploadFileAction
{
public function __construct(
private EntityManagerInterface $em,
private ValidatorInterface $validator,
) {}
public function __invoke(Request $request): MediaObject
{
$uploadedFile = $request->files->get('file');
$mediaObject = new MediaObject();
$mediaObject->setFile($uploadedFile);
$errors = $this->validator->validate($mediaObject);
if (count($errors) > 0) {
throw new \RuntimeException((string) $errors);
}
$this->em->persist($mediaObject);
$this->em->flush();
return $mediaObject;
}
}
- Testing dengan Postman
Endpoint:
POST /api/media_objectsBody: (form-data)
| Key | Type | Value |
|---|---|---|
| file | File | Pilih File |
Response:
{
"@id": "/api/media_objects/1",
"id": 1,
"filePath": "myfile.pdf"
}
6. Akses File
File akan disimpan di direktori:
public/uploads/files
Dan dapat diakses via URL:
http://localhost:8000/uploads/files/myfile.pdf
7. Tips Tambahan
-
Gunakan filter MIME type atau ukuran file di validator
-
Gunakan
serialization groupsuntuk menyembunyikan atau mengatur visibilitas -
Untuk update file, buat endpoint
PUTkhusus -
Gunakan CDN atau storage service (Amazon S3, Minio, dll) untuk production
Kesimpulan
✅ File upload dapat dilakukan dengan multipart/form-data
✅ Gunakan VichUploaderBundle untuk manajemen file dan nama file otomatis
✅ Upload dilakukan via controller custom
✅ Output bisa berupa path file atau URL publik
📂 Upload file dengan aman, rapi, dan RESTful di API Platform.