Precognition
Laravel Rest API supports Laravel Precognition. A precognitive request is authorized and validated like the real one, then stops before the endpoint runs: a form can show its errors as the user types.
Enabling Precognition
Precognition is off by default. Turn it on in config/rest.php:
'precognition' => [
'enabled' => true,
],
Every route that Rest::resource() registers then gets Laravel's HandlePrecognitiveRequests middleware. The value is read when the routes are registered.
Sending a precognitive request
POST /api/products/search
Precognition: true
Content-Type: application/json
{"search": {"limit": 10, "filters": [{"field": "name", "value": "Desk lamp"}]}}
- A valid request answers
204 No Content, with thePrecognition-Success: trueheader. - An invalid request answers
422with the errors, as the real request would. - The checks before validation still run: a denied check answers
403first. See Policies. - Nothing is written, no event runs, and neither an action nor a write asks for a confirmation. Keys outside the perimeter still dispatch
KeysOutOfReachwhen the request validates them.
Validating some keys only
Precognition-Validate-Only names the keys to validate, separated by commas. A name also covers the keys under it:
POST /api/products/search
Precognition: true
Precognition-Validate-Only: search.filters
{"search": {"limit": 7, "filters": [{"field": "name", "value": "Desk lamp"}]}}
This request answers 204: search.limit, which is not a page size of the resource, sits outside search.filters. With Precognition-Validate-Only: search, it answers:
{"message": "The selected search.limit is invalid.", "errors": {"search.limit": ["The selected search.limit is invalid."]}}
Errors that block a name
A name also reports the errors that stop its own validation, so a key never answers 204 while the real request fails above it:
- the errors of each key above the name, such as
search.filtersandsearch.filters.0forsearch.filters.0.field; - the errors of the keys that decide the rules of an entry above the name.
| Name | Also reports |
|---|---|
an attribute of a mutate entry, mutate.0.attributes.title | operation, and key when the operation takes one |
a key of a filter, search.filters.0.value | field and operator |
| a key under an include, an aggregate or a relation group | relation, and type for an aggregate |
| a key under a scope or an instruction | name |
| a key of a sort | field |
a field of an action or an instruction, fields.status | the name of the entry that sets it, fields.0.name |
a key under a MorphTo entry | type |
For example, a filter on an unknown field reports the field to a name that targets its value:
Precognition-Validate-Only: search.filters.0.value
{"search": {"filters": [{"field": "stock", "value": 3}]}}
{"message": "The selected search.filters.0.field is invalid.", "errors": {"search.filters.0.field": ["The selected search.filters.0.field is invalid."]}}
A list over its limit reports on its own key, also to a name below it. With limits.sizes.filters set to 2, three filters and the name search.filters.0.field give:
{"message": "The search.filters field must not have more than 2 items.", "errors": {"search.filters": ["The search.filters field must not have more than 2 items."]}}
The other keys beside these stay out: search.filters.0.value does not report an error of search.filters.1.value or search.limit.
Key queries
The keys of mutate and resources are checked with database queries. A Precognition-Validate-Only request runs a key query only for the key it names, and for the key of an entry above a name, such as mutate.0.key for mutate.0.attributes.title. A request that leaves resources out runs no key query.
OpenAPI Documentation
Document every endpoint of your resources in OpenAPI with Scramble, with typed bodies, responses and examples, and keep the document under test.
Artisan Commands
Generate resources from your tables, controllers, policies, actions, metrics and responses, and check perimeters, policies and relations with rest:check.