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.