outcomer/symfony-json-schema-validation

JSON Schema validation bundle for Symfony with OPIS integration

Maintainers

Package info

github.com/outcomer/symfony-json-schema-validation

Type:symfony-bundle

pkg:composer/outcomer/symfony-json-schema-validation

Statistics

Installs: 19

Dependents: 0

Suggesters: 0

Stars: 13

Open Issues: 0

v3.0.0 2026-03-02 14:28 UTC

This package is auto-updated.

Last update: 2026-05-28 17:18:36 UTC


README

GitHub Actions Latest Stable Version PHP Version Symfony Version License

Before

Typical Symfony API endpoint:

  • Request DTO
  • Symfony Validator constraints
  • OpenAPI annotations
  • Mapping logic

Same field described multiple times.

class CreateUserRequest
{
    #[Assert\NotBlank]
    #[Assert\Email]
    public string $email;
}

Plus OpenAPI annotations and mapping.

This logic is repeated in 3 different places in real projects.

After

One schema:

{
  "type": "object",
  "required": ["email"],
  "properties": {
    "email": {
      "type": "string",
      "format": "email"
    }
  }
}

Used for:

  • validation
  • request mapping
  • OpenAPI generation

One schema replaces all of this duplication.

⚡ Quick Start

Installation

composer require outcomer/symfony-json-schema-validation

Basic Usage

use Outcomer\Bundle\SymfonyJsonSchemaValidation\Attribute\MapRequest;

class UserController
{
    #[Route('/api/users', methods: ['POST'])]
    public function create(
        #[MapRequest('schemas/user-create.json')]
        UserCreateDto $user
    ): JsonResponse {
        // $user contains validated data from request body, query, path, and headers
        return new JsonResponse(['id' => $userService->create($user)]);
    }
}

JSON Schema Example

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "body": {
      "type": "object", 
      "properties": {
        "name": {"type": "string", "minLength": 1},
        "email": {"type": "string", "format": "email"}
      },
      "required": ["name", "email"]
    },
    "query": {
      "type": "object",
      "properties": {
        "locale": {"type": "string", "enum": ["en", "de", "fr"]}
      }
    },
    "headers": {
      "type": "object",
      "properties": {
        "x-api-version": {"type": "string", "pattern": "^v[1-9]$"}
      }
    }
  }
}

📚 Why

Read the story behind this bundle on Hashnode

📖 Documentation

Complete Documentation - Visit our comprehensive documentation website

Quick Links

🚀 Features

  • Single source of truth for API validation
  • No serializer groups
  • Automatic OpenAPI generation

When NOT to use this

Use API Platform if you need:

  • full CRUD automation
  • admin panels
  • heavy framework magic

Incremental adoption

You can use this bundle:

  • on a single endpoint
  • together with Symfony Validator
  • together with API Platform
  • without rewriting your application

No migration is required.

FAQ

Does this replace Symfony Validator?

No. You can use both together.

Does this work with API Platform?

Yes. The bundle can coexist with API Platform.

Is this all-or-nothing?

No. You can adopt it endpoint-by-endpoint.

Why use JSON Schema?

To avoid duplication between validation, request mapping and OpenAPI.

Is there vendor lock-in?

No. Your schemas remain standard JSON Schema documents.

🤝 Contributing

We welcome contributions! Please see our Contributing Guide for details.

📄 License

This project is licensed under the MIT License - see the LICENSE file for details.

Need Help?