basilicom/json-schema-request-validator-bundle
Installation
composer require basilicom/json-schema-request-validator-bundle
Register the bundle in config/bundles.php:
return [
// ...
Basilicom\JsonSchemaRequestValidator\JsonSchemaRequestValidatorBundle::class => ['all' => true],
];
Create a JSON Schema File
Save a schema (e.g., schemas/user_create.json) in a directory (e.g., config/schemas/):
{
"type": "object",
"properties": {
"name": { "type": "string" },
"email": { "type": "string", "format": "email" }
},
"required": ["name", "email"]
}
Implement the Controller Interface
Extend AbstractController and implement JsonSchemaRequestValidationControllerInterface:
use Basilicom\JsonSchemaRequestValidator\Controller\JsonSchemaRequestValidationControllerInterface;
class UserController extends AbstractController implements JsonSchemaRequestValidationControllerInterface
{
public function setJsonSchemaFilePathsInFilePathProvider(FilePathProvider $provider)
{
$provider->addRouteSchemaMapping('app_user_create', 'schemas/user_create.json');
}
public function create(Request $request): JsonResponse
{
// Validation handled automatically; proceed if valid
return new JsonResponse(['success' => true]);
}
}
Route Configuration Annotate your route with a name matching the schema mapping:
# config/routes.yaml
app_user_create:
path: /users
controller: App\Controller\UserController::create
methods: POST
Schema Organization
config/schemas/ or a dedicated bundle resource directory.app_user_create → schemas/user_create.json).schemas/base_user.json for common fields).Dynamic Schema Resolution
Override setJsonSchemaFilePathsInFilePathProvider to conditionally load schemas:
public function setJsonSchemaFilePathsInFilePathProvider(FilePathProvider $provider)
{
$provider->addRouteSchemaMapping('app_user_create', 'schemas/' . ($request->get('type') . '.json'));
}
Integration with Symfony Serializer
Combine with @Groups in entities for automatic schema generation (e.g., using API Platform or NelmioApiDocBundle):
use Symfony\Component\Serializer\Annotation\Groups;
class User {
#[Groups(['user:create'])]
public string $name;
}
Generate schemas via:
composer require api
vendor/bin/api generate:openapi
Validation Feedback Access validation errors in the controller:
public function create(Request $request): JsonResponse
{
$errors = $request->get('json_schema_errors', []);
if (!empty($errors)) {
return new JsonResponse(['errors' => $errors], 400);
}
// ...
}
Missing Schema Files
500 Internal Server Error if the schema file is missing or the path is invalid.FilePathProvider mappings:
$provider->addRouteSchemaMapping('route_name', '/full/path/to/schema.json');
Circular References in Schemas
draft-07) may fail with circular $ref definitions.draft-04 or simplify references:
{
"$ref": "#/definitions/User" // Avoid deep nesting
}
Case-Sensitive Route Names
app_user_create ≠ App_User_Create).Performance with Large Schemas
# config/packages/basilicom_json_schema_request_validator.yaml
basilicom_json_schema_request_validator:
cache_schema_compilation: true
Enable Detailed Errors Temporarily disable automatic rejection to inspect errors:
// config/packages/basilicom_json_schema_request_validator.yaml
basilicom_json_schema_request_validator:
throw_exceptions: true
Catch exceptions in the controller:
try {
// ...
} catch (JsonSchemaValidationException $e) {
return new JsonResponse(['error' => $e->getMessage()], 400);
}
Validate Schemas Independently
Use the JsonSchema component to test schemas before integration:
composer require justinrainbow/json-schema
use Justinrainbow\JsonSchema\Validator;
$validator = new Validator();
$result = $validator->validate($data, (object) $schema);
Custom Error Responses
Override the default 400 response by implementing a custom JsonSchemaValidator:
use Basilicom\JsonSchemaRequestValidator\Validator\JsonSchemaValidatorInterface;
class CustomJsonSchemaValidator implements JsonSchemaValidatorInterface
{
public function validate(Request $request, string $schema): bool
{
// Custom logic
return $valid;
}
public function onValidationFailed(Request $request, string $schema): Response
{
return new JsonResponse(['custom' => 'error'], 400);
}
}
Register it in services.yaml:
services:
Basilicom\JsonSchemaRequestValidator\Validator\JsonSchemaValidatorInterface: '@App\Validator\CustomJsonSchemaValidator'
Schema Versioning Support multiple schema versions per route:
public function setJsonSchemaFilePathsInFilePathProvider(FilePathProvider $provider)
{
$provider->addRouteSchemaMapping('app_user_create_v1', 'schemas/user_v1.json');
$provider->addRouteSchemaMapping('app_user_create_v2', 'schemas/user_v2.json');
}
Conditional Validation Skip validation for specific routes or requests:
public function create(Request $request): JsonResponse
{
if (!$request->headers->get('X-Skip-Validation')) {
// Validation runs automatically
}
// ...
}
Or disable globally:
# config/packages/basilicom_json_schema_request_validator.yaml
basilicom_json_schema_request_validator:
enabled: false
How can I help you explore Laravel packages today?