Lewati ke konten utama

Virtual Property di API Platform

Virtual property adalah properti yang tidak disimpan di database, tetapi tetap bisa dikirim atau ditampilkan melalui API. Ini berguna untuk:

  • Menampilkan properti turunan dari beberapa field (fullName)
  • Menyediakan data hasil perhitungan (totalPrice)
  • Menyembunyikan logika kompleks dari client

1. Definisi Virtual Property

Misalnya kita punya entity User:

use ApiPlatform\Metadata\ApiResource;
use Symfony\Component\Serializer\Annotation\Groups;

#[ApiResource(
normalizationContext: ['groups' => ['user:read']],
)]
class User
{
#[Groups(['user:read'])]
private string $firstName;

#[Groups(['user:read'])]
private string $lastName;

public function getFirstName(): string
{
return $this->firstName;
}

public function getLastName(): string
{
return $this->lastName;
}

#[Groups(['user:read'])]
public function getFullName(): string
{
return "{$this->firstName} {$this->lastName}";
}
}

getFullName() adalah virtual property yang bisa muncul di JSON response meskipun tidak ada field fullName di database.

2. Hasil Response

Jika client melakukan request ke /api/users/1, responsenya bisa seperti ini:

{
"firstName": "John",
"lastName": "Doe",
"fullName": "John Doe"
}

3. Virtual Property Tulis (Write-Only)

Kamu juga bisa membuat virtual property untuk input saja, misalnya plainPassword:

#[Groups(['user:write'])]
private ?string $plainPassword = null;

public function setPlainPassword(?string $plainPassword): void
{
$this->plainPassword = $plainPassword;
}
  • plainPassword digunakan client untuk mengirim data

  • Tetapi tidak pernah disimpan langsung ke database

4. Menyembunyikan Virtual Property di Swagger

Kalau kamu ingin agar properti hanya muncul di kode, bukan di dokumentasi:

use Symfony\Component\Serializer\Annotation\Ignore;

#[Ignore]
public function getInternalCode(): string
{
return 'INT-' . $this->id;
}

🛑 Ini membuat property tidak muncul di output maupun dokumentasi (tergantung penggunaan).

5. Virtual Property untuk Nested Resource

Contoh: Kita ingin menampilkan total komentar pada Post.

#[Groups(['post:read'])]
public function getCommentCount(): int
{
return count($this->comments);
}

Jangan lupa tambahkan post:read ke serialization context ApiResource.

6. Tips

  • Gunakan virtual property untuk menyederhanakan API bagi frontend

  • Gunakan #[Groups] agar hanya muncul pada context yang relevan

  • Hindari logika berat di virtual property jika tidak perlu

Kesimpulan Virtual property memungkinkan:

✅ Output field tambahan yang tidak disimpan di DB ✅ Input sementara dari client ✅ API lebih fleksibel dan informatif

💡 Sangat cocok untuk kasus seperti: fullName, isAvailable, total, plainPassword, dll.