custom-validator Skill
Create custom validation constraints for API Platform resources using Symfony constraints or Laravel validation rules.
- GitHub Stars
- 29
- Dateien
- 1
- Letzter Commit
- 22. Okt. 2026
- Lizenz
- —
- Erlaubte Tools
- —
Was macht der custom-validator Skill?
custom-validator ist ein Agent Skill. Create custom validation constraints for API Platform resources using Symfony constraints or Laravel validation rules.
Zusammenfassung erzeugt aus der SKILL.md des Skills.
Über den custom-validator skill
Developing complex business logic for API Platform resources is what this skill enables for backend developers. It provides the necessary patterns to implement custom validation constraints when standard Symfony or Laravel rules are insufficient for specific requirements. An agent should load this skill when a user needs to enforce domain-specific formats, check for uniqueness, or implement rate and plan limits during write operations.
For Symfony-based projects, the skill demonstrates how to create a Constraint class and a corresponding ConstraintValidator class to handle logic like account limit checks. It also covers class-level constraints for multi-field validation and callback validation for DTOs. For Laravel environments, it focuses on using the rules option within the ApiResource attribute, supporting arrays, closures, or FormRequest class-strings. This ensures that custom business rules correctly emit 422 ConstraintViolationList responses.
Was ein agent damit machen kann
- 1Enforce plan-based account limitsCreate a validator that prevents users from exceeding a specific number of accounts based on their current subscription plan.
Geschrieben basierend auf dem SKILL.md des skills. Jeder use case wurde gegen ein zitat daraus geprüft.
So installierst du den custom-validator Skill
Jeder Befehl kopiert den Skill-Ordner in das Skills-Verzeichnis des Clients. Starte den Client neu oder beginne eine neue Session, um ihn zu laden.Den custom-validator Skill in Plugin installieren
/plugin marketplace add api-platform/skillset /plugin install api-platform@api-platform-skillset
Den custom-validator Skill in Claude Code installieren
~/.claude/skills/custom-validator/SKILL.md
$ npx degit api-platform/skillset/skills/custom-validator ~/.claude/skills/custom-validatorDen custom-validator Skill in Claude Code (project) installieren
.claude/skills/custom-validator/SKILL.md
$ npx degit api-platform/skillset/skills/custom-validator .claude/skills/custom-validatorDen custom-validator Skill in Codex installieren
~/.agents/skills/custom-validator/SKILL.md
$ npx degit api-platform/skillset/skills/custom-validator ~/.agents/skills/custom-validatorDen custom-validator Skill in Gemini CLI installieren
~/.gemini/skills/custom-validator/SKILL.md
$ npx degit api-platform/skillset/skills/custom-validator ~/.gemini/skills/custom-validatorDen custom-validator Skill in Claude.ai installieren
npx degit api-platform/skillset/skills/custom-validator custom-validator && zip -r custom-validator.zip custom-validator # claude.ai → Customize → Skills → + → Create skill → Upload a skill → custom-validator.zip
SKILL.md
Auf GitHub ansehenCustom Validation Constraints
Create custom validators when built-in Symfony constraints are insufficient.
Constraint Class
<?php
namespace App\Validator;
use Symfony\Component\Validator\Constraint;
#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)]
class IsValidAccountLimit extends Constraint
{
public string $message = 'Account limit reached for your current plan.';
public int $limit = 50;
}
Validator Class
Convention: {ConstraintName}Validator in the same namespace.
<?php
namespace App\Validator;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;
class IsValidAccountLimitValidator extends ConstraintValidator
{
public function __construct(
private readonly UserHelper $userHelper,
private readonly AccountRepository $accountRepository,
) {}
public function validate(mixed $value, Constraint $constraint): void
{
if (!$constraint instanceof IsValidAccountLimit) {
throw new \InvalidArgumentException('Unexpected constraint type');
}
if (null === $value || '' === $value) {
return;
}
$user = $this->userHelper->getUser();
$count = $this->accountRepository->countByUser($user->getId());
if ($count >= $constraint->limit) {
$this->context->buildViolation($constraint->message)
->addViolation();
}
}
}
Usage on Properties
use App\Validator\IsValidAccountLimit;
use Symfony\Component\Validator\Constraints as Assert;
class Account
{
#[Assert\NotBlank(groups: ['account:write'])]
#[Assert\Email(groups: ['account:write'])]
#[IsValidAccountLimit(groups: ['account:write'])]
public ?string $address;
}
Class-Level Constraint (UniqueEntity)
For constraints that validate across multiple fields:
#[\Attribute(\Attribute::TARGET_CLASS | \Attribute::IS_REPEATABLE)]
class MongoDBUnique extends Constraint
{
public array $fields = [];
public string $message = 'This value is already used.';
public function getTargets(): string
{
return self::CLASS_CONSTRAINT;
}
}
Usage:
#[MongoDBUnique(fields: ['address'], groups: ['account:write', 'account:patch'])]
class Account {}
Validation Groups with Operations
Target a constraint to specific operations by passing groups: (as shown above)
and wiring those groups into each operation's validationContext — see
operations for the full per-operation setup.
Callback Validation
For quick one-off validation on DTOs:
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Component\Validator\Context\ExecutionContextInterface;
class SendMessage
{
public ?string $text = null;
public ?string $html = null;
#[Assert\Callback]
public function validateContent(ExecutionContextInterface $context): void
{
if (null === $this->text && null === $this->html) {
$context->buildViolation('Either text or html content is required.')
->atPath('text')
->addViolation();
}
}
}
Laravel
Laravel does not use Symfony Constraints/ConstraintValidator. Validation is
declared with Laravel validation rules via the
rules option on #[ApiResource] or per-operation (rules can be an array, a closure,
or a FormRequest class-string). The ValidateProvider runs them before the
processor and emits the same 422 ConstraintViolationList shape.
use ApiPlatform\Metadata\ApiResource;
use ApiPlatform\Metadata\Post;
#[ApiResource(rules: ['title' => 'required|min:2'])]
#[Post(rules: ['isbn' => ['required', 'string']])] // per-operation override
class Book extends Model {}
For business rules beyond built-in rules, write a Laravel custom rule (a class
implementing Illuminate\Contracts\Validation\ValidationRule, scaffold with
php artisan make:rule) or a closure rule, and reference it in rules. A
FormRequest class-string is also accepted — its authorize()/rules() run, and an
AuthorizationException maps to 403, ValidationException to 422. Validation groups
and Symfony validationContext do not apply on Laravel; scope rules per operation
instead. Partial PATCH can relax required to sometimes via
partial_patch_validation in config/api-platform.php.
Dateien in diesem Skill
1custom-validator Skill-Fragen
Wie installiere ich den custom-validator Skill in Claude Code?
Führe npx degit api-platform/skillset/skills/custom-validator ~/.claude/skills/custom-validator aus. Claude Code lädt Skills aus ~/.claude/skills (alle Projekte) oder .claude/skills (ein Projekt) und nutzt einen Skill, wenn seine Beschreibung zur Aufgabe passt.
Welche Clients können den custom-validator Skill nutzen?
Jeder Client, der das Agent Skills-Format liest: Claude Code, Codex, Gemini CLI und claude.ai (als ZIP hochladen). Skripte im Skill laufen nur dort, wo der Client Codeausführung erlaubt.
How do I create a custom validator in Symfony for API Platform?
You need to create a Constraint class and a corresponding Validator class following the {ConstraintName}Validator naming convention in the same namespace.