Form Validation di API Platform
Validasi form pada API Platform sangat penting untuk menjaga integritas data. API Platform menggunakan Symfony Validator untuk menangani validasi field saat entitas dikirim melalui endpoint REST API.
1. Menambahkan Validasi ke Entity
Validasi dilakukan menggunakan constraint annotation atau konfigurasi YAML/XML. Contoh menggunakan PHP attribute:
use Symfony\Component\Validator\Constraints as Assert;
use ApiPlatform\Metadata\ApiResource;
use Symfony\Component\Serializer\Annotation\Groups;
#[ApiResource(
normalizationContext: ['groups' => ['user:read']],
denormalizationContext: ['groups' => ['user:write']]
)]
class User
{
#[Groups(['user:read'])]
private ?int $id = null;
#[Assert\NotBlank]
#[Assert\Email]
#[Groups(['user:read', 'user:write'])]
private ?string $email = null;
#[Assert\NotBlank]
#[Assert\Length(min: 6)]
#[Groups(['user:write'])]
private ?string $plainPassword = null;
}
2. Menampilkan Pesan Validasi
Jika client mengirim data tidak valid, API Platform otomatis merespons error:
Request:
{
"email": "",
"plainPassword": "123"
}
Response:
{
"@context": "/api/contexts/ConstraintViolationList",
"@type": "ConstraintViolationList",
"hydra:title": "An error occurred",
"hydra:description": "email: This value should not be blank.\nemail: This value is not a valid email address.\nplainPassword: This value is too short. It should have 6 characters or more.",
"violations": [
{
"propertyPath": "email",
"message": "This value should not be blank."
},
{
"propertyPath": "email",
"message": "This value is not a valid email address."
},
{
"propertyPath": "plainPassword",
"message": "This value is too short. It should have 6 characters or more."
}
]
}
3. Validasi Berdasarkan Grup
Kamu dapat menggunakan validation groups agar validasi hanya dijalankan pada context tertentu, misalnya saat POST
saja:
use Symfony\Component\Validator\Constraints as Assert;
#[Assert\NotBlank(groups: ['register'])]
#[Groups(['user:write'])]
private ?string $plainPassword = null;
Dan daftarkan validationContext
di ApiResource
:
#[ApiResource(
operations: [
new \ApiPlatform\Metadata\Post(validationContext: ['groups' => ['register']])
]
)]
4. Validasi Kustom
Jika validasi standar tidak cukup, kamu bisa membuat constraint sendiri:
// src/Validator/UniqueEmail.php
use Symfony\Component\Validator\Constraint;
#[\Attribute]
class UniqueEmail extends Constraint
{
public string $message = 'Email {{ value }} sudah terdaftar.';
}
Dan validaturnya:
// src/Validator/UniqueEmailValidator.php
use Symfony\Component\Validator\ConstraintValidator;
class UniqueEmailValidator extends ConstraintValidator
{
public function __construct(private UserRepository $repo) {}
public function validate($value, Constraint $constraint)
{
if ($this->repo->findOneBy(['email' => $value])) {
$this->context->buildViolation($constraint->message)
->setParameter('{{ value }}', $value)
->addViolation();
}
}
}
5. Validasi di validation.yaml
Jika kamu lebih suka YAML daripada atribut:
# config/validator/validation.yaml
App\Entity\User:
properties:
email:
- NotBlank: ~
- Email: ~
plainPassword:
- NotBlank: ~
- Length:
min: 6
6. Testing Validasi (Opsional)
Gunakan PHPUnit untuk menguji bahwa validasi berjalan sesuai ekspektasi:
public function testBlankEmail()
{
$client = static::createClient();
$client->request('POST', '/api/users', [
'json' => ['email' => '', 'plainPassword' => '123456']
]);
$this->assertResponseStatusCodeSame(422);
$this->assertJsonContains([
'violations' => [
['propertyPath' => 'email']
]
]);
}