Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Json Schema Laravel Package

justinrainbow/json-schema

Validate JSON data against JSON Schema in PHP. Supports draft-3, draft-4, draft-6, and draft-7 with $ref resolution and detailed validation errors. Install via Composer and validate decoded JSON objects against local or remote schemas.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture Fit

  • Schema Validation Layer: Fits seamlessly into Laravel’s request validation pipeline (e.g., FormRequest, ApiResource). Can replace or augment Laravel’s built-in validation for complex JSON payloads (e.g., API requests, nested data structures).
  • API Contracts: Ideal for enforcing OpenAPI/Swagger schemas or internal JSON contracts (e.g., event payloads, microservice messages).
  • Data Transformation: Supports type coercion and default values, enabling schema-driven data normalization (e.g., converting string "true" to boolean true).
  • Modularity: Lightweight (~1MB) and dependency-light (no heavy frameworks), making it suitable for microservices or monoliths.

Integration Feasibility

  • Laravel Ecosystem Compatibility:
    • Works with Laravel’s Request objects (via json()->all() or input()).
    • Can integrate with Laravel’s Validator facade via custom rules or service providers.
    • Supports Laravel’s event system (e.g., validate payloads in Validating events).
  • Schema Storage:
    • Supports remote schemas (HTTP/HTTPS) and local files (file://), enabling dynamic schema loading (e.g., from a config service or database).
    • SchemaStorage class allows caching/resolving $ref references (e.g., for reusable sub-schemas).
  • Performance:
    • Draft-7 validation is optimized but may introduce overhead for high-throughput APIs. Benchmark against Laravel’s native validation for critical paths.

Technical Risk

  • Draft Compatibility:
    • Risk: Partial support for Draft-7 (e.g., missing features like contentMediaType). Validate against your schema’s draft requirements.
    • Mitigation: Use Constraint::CHECK_MODE_STRICT for Draft-6 if strict compliance is needed.
  • Type Coercion Side Effects:
    • Risk: CHECK_MODE_COERCE_TYPES modifies input data, which may conflict with Laravel’s immutable request handling (e.g., Illuminate\Http\Request).
    • Mitigation: Clone input data before validation or use coerce() sparingly.
  • Error Handling:
    • Risk: Default error messages may not align with Laravel’s validation language (e.g., property.x is required vs. property.x: "must be string").
    • Mitigation: Customize error formatting via Validator::setErrorFormatter() or map errors to Laravel’s Validator exceptions.
  • PHP Version:
    • Risk: Requires PHP 7.2+. Laravel 10+ (PHP 8.1+) is fully compatible, but older Laravel versions may need polyfills.
    • Mitigation: Test with your PHP version; use return_type_declaration and strict_types if enabled.

Key Questions

  1. Schema Source:
    • Will schemas be static (e.g., resources/schemas/) or dynamic (e.g., fetched from a config service)?
    • How will $ref resolution handle remote schemas (caching, retries, auth)?
  2. Validation Granularity:
    • Should validation run at the controller level (e.g., validateRequest()), middleware level (e.g., API gateway), or service level (e.g., domain logic)?
  3. Error Integration:
    • How should validation errors map to Laravel’s Validator (e.g., custom error bags, API responses)?
  4. Performance:
    • For high-volume APIs, will schema compilation (e.g., SchemaStorage) be cached?
    • Should validation be async (e.g., queue jobs for heavy schemas)?
  5. Testing:
    • How will schema tests integrate with Laravel’s testing (e.g., createJsonTest())?
    • Will you use the package’s test suite to validate compliance?

Integration Approach

Stack Fit

  • Laravel-Specific Integrations:
    • FormRequest/ApiResource: Override rules() to return schema objects or use a custom SchemaValidator trait.
      use JsonSchema\Validator;
      use JsonSchema\Constraints\Constraint;
      
      class StoreRequest extends FormRequest {
          public function rules(): array {
              $validator = new Validator();
              $validator->validate(
                  $this->json()->all(),
                  (object)['type' => 'object', 'properties' => [...]],
                  Constraint::CHECK_MODE_COERCE_TYPES
              );
              return []; // Skip Laravel's validator
          }
      }
      
    • Service Provider: Register a SchemaValidator facade or bind the package to Laravel’s container.
      $this->app->singleton(Validator::class, function () {
          return new Validator(new Factory(new SchemaStorage()));
      });
      
    • Middleware: Validate incoming requests before routing (e.g., for API gateways).
      public function handle(Request $request, Closure $next) {
          $validator = app(Validator::class);
          $validator->validate($request->json()->all(), $this->schema);
          return $next($request);
      }
      
  • Event-Driven Validation:
    • Listen to Illuminate\Validation\Validating events to inject schema validation.
    • Use Illuminate\Bus\DispatchesJobs to queue validation for async processing.

Migration Path

  1. Pilot Phase:
    • Start with non-critical endpoints (e.g., admin panels, internal APIs).
    • Replace simple Laravel validation (e.g., required|string) with schema validation for complex payloads.
  2. Incremental Adoption:
    • Step 1: Use for request validation (replace FormRequest::rules()).
    • Step 2: Extend to internal data structures (e.g., event payloads, service inputs).
    • Step 3: Replace Laravel’s Validator entirely for API contracts (if performance allows).
  3. Fallback Strategy:
    • Hybrid approach: Use Laravel’s validator for simple rules and json-schema for complex schemas.
    • Example:
      $validator = Validator::make($request->all(), [
          'nested.data' => ['json_schema' => file_get_contents('schema.json')],
      ]);
      

Compatibility

  • Laravel Versions:
    • Laravel 10+ (PHP 8.1+): Full compatibility; leverage PHP 8 features (e.g., named arguments, attributes).
    • Laravel 9 (PHP 8.0): Test for PHP 8.0-specific issues (e.g., idn_to_ascii deprecation).
    • Laravel 8 (PHP 7.4): May require polyfills for PHP 7.2+ features.
  • Existing Validation:
    • Conflict: Avoid mixing Laravel’s Validator and json-schema for the same payload to prevent double-validation.
    • Solution: Use json-schema as the source of truth and map errors to Laravel’s format.
  • Third-Party Packages:
    • API Tools: Compatible with Laravel API resources (e.g., spatie/laravel-api-resources).
    • Testing: Works with laravel/pint, phpunit, and pestphp for schema-driven tests.

Sequencing

  1. Schema Design:
    • Define schemas in resources/schemas/ or a database (e.g., for dynamic APIs).
    • Use tools like JSON Schema Generator to auto-generate schemas from sample data.
  2. Core Integration:
    • Implement a SchemaValidator service to centralize validation logic.
    • Example:
      class SchemaValidator {
          public function __construct(private Validator $validator) {}
      
          public function validate(array $data, string|object $schema): void {
              $this->validator->validate($data, $schema);
              if (!$this->validator->isValid()) {
                  throw new ValidationException($this->validator->getErrors());
              }
          }
      }
      
  3. Error Handling:
    • Create a custom ValidationException that formats json-schema errors for Laravel’s Validator.
    • Example:
      throw ValidationException::withMessages([
          'property.x' => collect($validator->getErrors())
              ->map(fn($e) => $e['message'])
              ->unique()
              ->values()
              ->toArray(),
      ]);
      
  4. Testing:
    • Write schema tests using the package’s test suite or Laravel’s JsonTestCase.
    • Example:
      public function test_schema_validation() {
          $validator = new Validator();
          $validator->validate(['data' => 'test'], (object)['type' => 'object', 'properties' => [...]]);
          $this->assertTrue($validator->isValid());
      }
      
  5. Performance Optimization:
    • Cache compiled schemas (e.g., using Laravel’s cache or SchemaStorage).
    • Benchmark validation time for high-traffic endpoints.

Operational Impact

Maintenance

  • Schema Updates:
    • Pros: Schemas are version-controlled (e.g., in Git) and can be updated independently of code.
    • Cons: Breaking schema changes require backward-com
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
davejamesmiller/laravel-breadcrumbs
artisanry/parsedown
bower-asset/punycode
bower-asset/inputmask
bower-asset/jquery
bower-asset/yii2-pjax
laravel/nova
spatie/laravel-mailcoach
spatie/laravel-superseeder
laravel/liferaft
nst/json-test-suite
danielmiessler/sec-lists
jackalope/jackalope-transport
twbs/bootstrap4
php-http/client-implementation
phpcr/phpcr-implementation
cucumber/gherkin-monorepo
haydenpierce/class-finder
psr/simple-cache-implementation
uri-template/tests