Weave 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 Laravel Package

webmozart/json

A robust PHP library for decoding, encoding, and validating JSON. It provides clear error messages with line and column details, JSON Schema validation, and convenient file handling via JsonFile, making JSON processing safer and easier in PHP applications.

Deep Wiki
Context7

Getting Started

  1. Install via Composer (no Laravel auto-discovery; there is no facade):
    composer require webmozart/json
    
  2. Look first at Webmozart\Json\JsonDecoder and Webmozart\Json\JsonEncoder; everything else is error plumbing (JsonException, JsonError). The README on the Packagist page is a single-page API; the tests/ directory is the real usage manual.
  3. Basic use case — validate an inbound webhook body against a schema file:
    use Webmozart\Json\JsonDecoder;
    
    $decoder = new JsonDecoder('file://'.storage_path('schemas/webhook.json'));
    
    $payload = $decoder->decode($request->getContent());
    
    The decoder throws JsonException on parse or schema failure, so one try/catch covers both.
  4. Next useful step: read JSON config/fixtures from disk without file_get_contents + json_decode boilerplate:
    $data = (new JsonDecoder())->decodeFile(base_path('composer.json'));
    

Implementation Patterns

Service container binding. Wrap the decoder in a singleton so the schema path is configured once and can be swapped in tests:

// AppServiceProvider::register()
$this->app->singleton(JsonDecoder::class, fn () =>
    new JsonDecoder('file://'.storage_path('schemas/payload.json'))
);

Type-hint JsonDecoder in controllers, jobs, or a dedicated PayloadValidator.

A reusable validation service. Rather than sprinkling try/catch across controllers, centralise the mapping between JsonError and a 422 response:

public function validate(string $json): array
{
    try {
        return $this->decoder->decode($json);
    } catch (JsonException $e) {
        throw ValidationException::withMessages([
            'json' => array_map(
                fn ($err) => sprintf('%s: %s', $err->getPropertyPath(), $err->getMessage()),
                $e->getErrors()
            ),
        ]);
    }
}

getErrors() returns JsonError[]; getPropertyPath() gives you the JSON Pointer-ish path (/items/0/sku), which is ideal for error text.

Middleware for webhook routes. For third-party webhooks (Stripe-style, GitHub-style) you often want schema validation before the controller runs and before any side effects. A ValidateJsonSchema middleware that reads $request->getContent() and aborts with 422 keeps controllers thin. Don't forget to allow Content-Type: application/json and use raw content, not $request->all().

Fixture / config validation in tests. This is where the package shines day-to-day: load every JSON fixture in tests/fixtures/ and assert it conforms to the schema.

it('has valid fixtures', function () {
    $decoder = new JsonDecoder('file://'.base_path('schemas/fixture.schema.json'));
    foreach (glob(base_path('tests/fixtures/*.json')) as $file) {
        expect(fn () => $decoder->decodeFile($file))->not->toThrow(JsonException::class);
    }
});

Combine this with JsonEncoder::setPrettyPrinting(true) and encodeFile() if you regenerate fixtures.

Round-trip encode/decode for exports. For API responses or data exports:

$encoder = new JsonEncoder();
$encoder->setPrettyPrinting(true);   // readable in PRs, disabled in prod
$encoder->encodeFile($path, $data);
$encoder->encode($data);             // string for a JsonResponse body

Or skip the encoder for response bodies and pass the array to Laravel's response()->json() — you only need JsonEncoder when writing files or when you need strict control over pretty-printing/trailing newlines.

Schema composition. Since the package delegates to justinrainbow/json-schema, $ref between local schema files works if the URIs are correct. Keep schemas in storage/schemas and reference them with file:// absolute URIs so relative $refs resolve predictably.

Gotchas and Tips

  • Age and compatibility. Last release 2016; the code targets PHP 5.x and older justinrainbow/json-schema. Pin and test on your PHP version — don't add it to a Laravel 11 app without a green test run first. If you only need validation, justinrainbow/json-schema (or modern opis/json-schema) alone is lighter; webmozart's value is the codec convenience wrapper.
  • Schema paths are URIs, not filesystem paths. Passing storage_path('schema.json') works sometimes and fails when $ref resolution kicks in. Use 'file://'.realpath($path) for anything with nested references.
  • One exception type for two failures. A malformed JSON string and a schema violation both throw JsonException. Inspect $e->getErrors() — a parse error has a syntax-flavoured message, schema errors carry property paths. If your app treats these differently (400 vs 422), branch on the error source or wrap the parse separately.
  • decodeFile vs decode(file_get_contents(...)). Always prefer decodeFile; it handles stream opening, I/O errors, and gives you clean exception messages instead of PHP warnings.
  • Empty input throws, not returns null. A blank webhook body or an empty Content-Type payload will raise an exception. Guard with trim($body) !== '' before decoding if that's a legitimate case in your endpoint.
  • Encoding quirks. JsonEncoder::encode returns a string; it does not throw on failure by default configuration — check your error handling if you encode user-controlled data with JSON_UNESCAPED_UNICODE-style expectations. Set pretty printing only outside production to avoid bloated payloads.
  • Everything is in memory. Neither decoder nor encoder streams; multi-megabyte JSON payloads will spike memory. For large imports/exports, prefer json_decode with JSON_THROW_ON_ERROR in a line-oriented/streaming loop and reserve this package for schema-validated, bounded payloads.
  • Don't mix with Laravel's $request->all(). The package wants the raw string; Laravel's request parsing already calls json_decode and silently nulls out malformed bodies, so you'll never see the parse error the schema validation is trying to report.
  • Extension points. Subclass JsonDecoder/JsonEncoder if you need custom error formatting or default encoder flags; both are small and non-final. For anything more, swap in opis/json-schema behind a small interface — the Webmozart\Json\JsonDecoder API surface (decode, decodeFile, decodeStream) is trivial to mimic, which keeps an eventual migration cheap.
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.
diephp/sequences
users-au/socialite-provider
twidpay/twid-logger
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle