Form Requests
The toolkit provides a base FormRequest class that extends Laravel's with support for query parameter validation and strict unknown parameter rejection.
Basic Usage
use BlueBeetle\ApiToolkit\Http\Requests\FormRequest;
use BlueBeetle\ApiToolkit\Rules\ValidInclude;
use BlueBeetle\ApiToolkit\Rules\ValidPageSize;
class ListProductsRequest extends FormRequest
{
public function queryParamRules(): array
{
return [
'filter.name' => ['sometimes', 'string', 'max:255'],
'filter.status' => ['sometimes', 'in:active,archived,draft'],
'page.size' => ['sometimes', new ValidPageSize()],
'include' => ['sometimes', new ValidInclude(['category', 'tags'])],
];
}
public function queryParamMessages(): array
{
return [
'filter.status.in' => 'Status must be one of: active, archived, draft.',
];
}
public function queryParamAttributes(): array
{
return [
'filter.name' => 'product name',
];
}
}
Available Methods
| Method | Purpose |
|---|---|
queryParamRules() | Validation rules for query parameters |
queryParamMessages() | Custom error messages for query parameter validation |
queryParamAttributes() | Human-readable names for query parameters (used in error messages) |
rules() | Validation rules for request body (inherited from Laravel) |
messages() | Custom error messages for body validation (inherited from Laravel) |
Strict Parameter Checking
Unlike standard Laravel form requests, the toolkit's FormRequest rejects unknown parameters with a 400 Bad Request. If a client sends ?filter[foo]=bar and foo isn't in your rules, the request is rejected immediately, before validation rules run.
This applies to both query parameters and request body fields.
{
"errors": [
{
"status": "400",
"code": "invalid_request_error",
"title": "Bad Request",
"detail": "Received unknown parameter: foo"
}
]
}
Body Validation
For write operations, use the standard rules() method:
use BlueBeetle\ApiToolkit\Http\Requests\FormRequest;
class CreateProductRequest extends FormRequest
{
public function rules(): array
{
return [
'name' => ['required', 'string', 'max:255'],
'description' => ['sometimes', 'string'],
'price' => ['required', 'numeric', 'min:0'],
'category_id' => ['required', 'exists:categories,id'],
];
}
}
Combining Query and Body Rules
use BlueBeetle\ApiToolkit\Http\Requests\FormRequest;
use BlueBeetle\ApiToolkit\Rules\ValidInclude;
class UpdateProductRequest extends FormRequest
{
public function queryParamRules(): array
{
return [
'include' => ['sometimes', new ValidInclude(['category'])],
];
}
public function rules(): array
{
return [
'name' => ['sometimes', 'string', 'max:255'],
'price' => ['sometimes', 'numeric', 'min:0'],
];
}
}
Using in Controllers
The toolkit includes custom validation rules like ValidInclude and ValidPageSize for common JSON:API parameters. See Validation Rules for the full list.
Type-hint the form request in your controller method. Laravel resolves and validates it automatically:
use App\Http\Requests\CreateProductRequest;
use App\Http\Requests\ListProductsRequest;
use App\Http\Resources\ProductResource;
use App\Models\Product;
use BlueBeetle\ApiToolkit\Http\Response;
use BlueBeetle\ApiToolkit\QueryBuilder;
class ProductController
{
public function index(ListProductsRequest $request)
{
return QueryBuilder::for(Product::class, $request)
->fromResource(ProductResource::class)
->paginate();
}
public function store(CreateProductRequest $request, Response $response)
{
$product = Product::create($request->validated());
return $response->success($product, ProductResource::class)
->respond(201);
}
}