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_objects
Body: (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 groups
untuk menyembunyikan atau mengatur visibilitas -
Untuk update file, buat endpoint
PUT
khusus -
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.