Lewati ke konten utama

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;
}
}
  1. Testing dengan Postman Endpoint: POST /api/media_objects Body: (form-data)
KeyTypeValue
fileFilePilih 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.