br-write-schema
Configure Better Route 1.1 Resource writeSchema or payloadSchema validation for create and update payloads. Use when defining writable fields, coercion, sanitization, required and nullable values, len
SKILL.mdbetter-route/br-write-schema/SKILL.md
GitHubBetter Route Resource write schema
Use writeSchema() to validate and normalize Resource create/update payload fields. payloadSchema() is an exact alias.
Resource::make('articles')
->allow(['create', 'update'])
->fields(['id', 'title', 'status', 'priority', 'published_at'])
->writeSchema([
'title' => [
'type' => 'string',
'required' => true,
'sanitize' => 'text',
'minLength' => 1,
'maxLength' => 180,
],
'status' => [
'type' => 'enum',
'values' => ['draft', 'published'],
],
'priority' => ['type' => 'int', 'min' => 0, 'max' => 100],
'published_at' => ['type' => 'date', 'nullable' => true],
]);
The enum allowlist is flat: use ['type' => 'enum', 'values' => [...]]. Do not nest values under an enum key.
Rule contract
- Type strings may be supplied directly, such as
'title' => 'string'. - Supported coercion types are
int/integer,float/number,bool/boolean,string,date,email,url,enum,array,object, andmixed. requiredis enforced only oncreate; updates may be partial but must contain at least one writable field.nullable: trueacceptsnull; otherwisenullfails validation.- String constraints are
minLength,maxLength, andregex. Numeric constraints areminandmax. emailandurluse PHP validation after coercion/sanitization.dateis only string coercion; validate date format withregexor a callable sanitizer/other domain layer.- Sanitizers are
text,email,key,url, or a callable receiving(value, field). An unknown sanitizer string leaves the value unchanged, so never treat arbitrary names as validation. - Callable sanitizers transform values; they are not authorization checks and must return a value compatible with subsequent constraints.
Resource writable fields come from configured fields minus the ID field. Unknown payload keys fail with 400 validation_failed; they are not silently dropped. A field denied by fieldPolicy also fails, rather than disappearing from the write.
Validation errors use the standard error envelope with details.fieldErrors. Boolean fieldPolicy: false produces a 400 non-writable validation error; failed capabilities or policy callbacks produce 403 errors. Follow br-resource-policy for authorization.
Checks
- Test unknown, empty, null, malformed, boundary, and coerced values.
- Test required fields separately on create and partial update.
- Test enum values with strict type expectations; enum values are compared strictly after string coercion.
- Anchor regexes and set explicit maximum lengths before expensive domain processing.
- Do not add
patchtoallow(); the Resource action name isupdate, even though its route handles update semantics.
Source reference: src/Resource/Resource.php (readPayload, coercePayloadValue, assertValueConstraints, validationError).
References
- Official documentation: https://lonsdale201.github.io/better-docs/docs/better-route/agents