Lewati ke konten utama

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']
]
]);
}