Validation
Configure validators per column to enforce data integrity on write operations. Validators run on every POST, PUT, and PATCH request before the record is written.
Auto-derivation from TCA
TCA API reads your existing TCA configuration at boot time and automatically derives validators from constraints that are already declared there. No configuration is required in your resource definition — the constraints are picked up for free.
The following TCA constraints are derived automatically:
| TCA column type | TCA key | Derived validator | Notes |
|---|---|---|---|
input, text | config.max | maxLength | Derived when max > 0 |
number | config.range.lower | minValue | Only when lower is set |
number | config.range.upper | maxValue | Only when upper is set |
group, inline, file, category | config.maxitems | maxItems | Always derived when set |
group, inline, file, category | config.minitems | minItems | Only when minitems > 0 |
| any | config.required | required flag | Standard TYPO3 field flag |
Derivation is gap-fill only: if you declare an explicit validator of the same type in the resource config, the TCA-derived one is skipped for that type. Explicit configuration always wins.
// TCA declares max=255 for 'title', but your resource sets maxLength=20 —
// the explicit maxLength=20 is kept and 255 is NOT added.
'title' => [
'groups' => ['list', 'show', 'create', 'update'],
'validators' => [
['type' => 'maxLength', 'max' => 20], // wins over TCA max=255
],
],
// 'first_name' has no explicit validators — TCA max=255 is injected automatically.
'first_name' => [
'groups' => ['list', 'show', 'create', 'update'],
],
// 'profile_photo' (type=file, maxitems=1 in TCA) — maxItems:1 injected automatically.
'profile_photo' => [
'groups' => ['list', 'show', 'create', 'update'],
'upload' => ['folder' => '1:/uploads/'],
],
Opt-out per column
To disable all TCA derivation for a specific column, set `'tca`:
'notes' => [
'groups' => ['list', 'show', 'create', 'update'],
'tcaValidation' => false, // no validators derived from TCA for this column
],
The required flag follows the same gap-fill rule: it is only injected from
TCA when the required key is completely absent from the column config. An
explicit 'required' => false is honored and never overridden.
Validator types
The following validator types are available, both for explicit configuration and as targets for TCA auto-derivation.
| Type | Parameters | Error code | Description |
|---|---|---|---|
required | (none) | REQUIRED | Field must be present and non-empty on POST/PUT. Set via the required
column key, not inside validators. Skipped on PATCH for absent fields.
Auto-derived from TCA config.required: true. |
maxLength | max (int) | MAX_LENGTH | Maximum string length (multi-byte safe).
Auto-derived from input/text TCA config.max. |
minLength | min (int) | MIN_LENGTH | Minimum string length. |
maxValue | max (int|float) | MAX_VALUE | Maximum numeric value. Skipped for non-numeric values.
Auto-derived from number TCA config.range.upper. |
minValue | min (int|float) | MIN_VALUE | Minimum numeric value. Skipped for non-numeric values.
Auto-derived from number TCA config.range.lower. |
maxItems | max (int) | MAX_ITEMS | Maximum number of items in an array-valued relation field. Skipped for
non-array values. Auto-derived from group/inline/file/
category TCA config.maxitems. |
minItems | min (int) | MIN_ITEMS | Minimum number of items. Skipped for non-array values.
Auto-derived from config.minitems when > 0. |
regex | pattern (string) | REGEX | PCRE pattern (including delimiters) the value must match. The pattern is validated at config load time — broken patterns raise an exception immediately rather than silently failing at runtime. |
Configuration
Validators are declared in the validators array of a column definition:
'columns' => [
'title' => [
'groups' => ['list', 'show', 'create', 'update'],
'required' => true,
'validators' => [
['type' => 'maxLength', 'max' => 255],
['type' => 'minLength', 'min' => 3],
['type' => 'regex', 'pattern' => '/^[\w\s]+$/u'],
],
],
'rating' => [
'groups' => ['list', 'show', 'create', 'update'],
'validators' => [
['type' => 'minValue', 'min' => 1],
['type' => 'maxValue', 'max' => 5],
],
],
],
Error response
Validation failures return 422 Unprocessable Entity with a Hydra-compatible error body. All violations are collected and returned together — the request is not aborted on the first failure.
{
"@context": "http://www.w3.org/ns/hydra/context.jsonld",
"@type": "hydra:Error",
"hydra:title": "Validation Failed",
"hydra:description": "2 validation error(s)",
"violations": [
{
"propertyPath": "title",
"message": "Field 'title' is required.",
"code": "REQUIRED"
},
{
"propertyPath": "rating",
"message": "Field 'rating' must not exceed 5.",
"code": "MAX_VALUE"
}
]
}
PATCH behaviour
On PATCH requests (partial updates), validation only runs on fields that are
present in the request body. Absent fields — including required ones — are
skipped. Auto-derived validators follow the same rule.