Lewati ke konten utama

Autofill Using Interface di API Platform

Dalam pengembangan API, sering kali kita ingin agar field tertentu otomatis terisi berdasarkan data kontekstual, seperti user login, waktu saat ini, atau entitas terkait. Untuk membuat mekanisme ini reusable, kita dapat menggunakan interface dan event listener di API Platform.


1. Tujuan

Contoh kebutuhan:

  • Set createdBy ke user login saat entitas dibuat
  • Set updatedAt setiap kali entitas diubah
  • Otomatis isi organization berdasarkan user login

Dengan interface, kita bisa menandai entitas mana yang perlu autofill, lalu isi field tersebut secara otomatis dengan listener.


2. Buat Interface

CreatedByAwareInterface.php

namespace App\Entity\Contract;

use App\Entity\User;

interface CreatedByAwareInterface
{
public function setCreatedBy(?User $user): void;
}

3. Implementasi di Entitas

Comment.php

use App\Entity\Contract\CreatedByAwareInterface;

class Comment implements CreatedByAwareInterface
{
private ?User $createdBy = null;

public function setCreatedBy(?User $user): void
{
$this->createdBy = $user;
}
}

4. Listener untuk Autofill

AutofillListener.php

namespace App\EventListener;

use Symfony\Component\HttpKernel\Event\ViewEvent;
use Symfony\Component\Security\Core\Security;
use App\Entity\Contract\CreatedByAwareInterface;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\EventDispatcher\Attribute\AsEventListener;

#[AsEventListener(event: KernelEvents::VIEW, method: 'onKernelView', priority: 100)]
class AutofillListener
{
public function __construct(private Security $security) {}

public function onKernelView(ViewEvent $event): void
{
$entity = $event->getControllerResult();
$method = $event->getRequest()->getMethod();

if ($method !== 'POST') {
return;
}

if ($entity instanceof CreatedByAwareInterface) {
$entity->setCreatedBy($this->security->getUser());
}
}
}

5. Penjelasan

  • Listener ini berjalan hanya saat request POST.

  • Jika entitas mengimplementasikan CreatedByAwareInterface, maka field createdBy akan otomatis terisi dengan user login.

6. Kombinasi dengan Banyak Interface

Kamu bisa tambahkan interface lain seperti:

interface UpdatedAtAwareInterface { public function setUpdatedAt(\DateTimeImmutable $time): void; }
interface OwnedByOrganizationInterface { public function setOrganization(Organization $org): void; }

Lalu cek di listener:

if ($entity instanceof UpdatedAtAwareInterface) {
$entity->setUpdatedAt(new \DateTimeImmutable());
}

7. Keuntungan Pendekatan Ini

✅ Reusable — cukup implement interface, autofill otomatis ✅ Clean — tanpa harus tambah logic di controller/persister ✅ Terstandarisasi — logika bisnis tidak tercecer ✅ Testable — bisa dites unit/functional dengan mudah

8. Contoh Output Response

Request:

POST /api/comments
Authorization: Bearer <token>
Content-Type: application/json

{
"content": "Komentar baru"
}

Response:

{
"@id": "/api/comments/10",
"content": "Komentar baru",
"createdBy": "/api/users/5"
}

Tanpa kirim createdBy, field ini otomatis terisi oleh listener.

Kesimpulan ✅ Gunakan interface untuk menandai entitas yang butuh autofill ✅ Gunakan event listener untuk logika otomatis ✅ Bisa digunakan untuk user, waktu, organisasi, dsb ✅ Clean dan aman — tanpa manipulasi client-side

🧠 Ini adalah praktik OOP yang bagus dan menjaga kode tetap modular & maintainable.