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 Request Bundle Laravel Package

filament-uno/json-request-bundle

Simplify JSON request handling in Laravel and Filament with a ready-made request bundle. Standardize validation, parsing, and structured responses so your app's JSON APIs and Filament workflows stay consistent, maintainable, and easy to extend.

View on GitHub
Deep Wiki
Context7

Getting Started

Read this first: it is a Symfony bundle, not a Laravel package. There is no service provider, no config/json-request.php, and no composer require that will auto-register anything in a Laravel app. As a Laravel developer your day-to-day leverage from installing this is zero — the value is in the pattern it encodes, which you can reproduce with FormRequest plus a DTO in about 20 minutes.

What v1.0.0 actually changes: nothing you can design around. The release note is a single line — "based off the original SymfonyBundles JsonRequest bundle, commit fa0e3d252c244aea89ef44866c404b29cfd6dc4c". That is provenance, not a changelog. There is no list of breaking changes, no new features, no deprecations, no version-support matrix. Treat 1.0.0 as a version-number reset on 2020-era code, not as a maturity or maintenance signal. The practical consequence is that the code is now exactly pin-downable: you can diff this repo against that commit and the answer to "what does it do?" is whatever that commit did.

If you are actually working in a Symfony codebase (or evaluating a legacy one):

  1. composer require filament-uno/json-request-bundle — expect the resolver to fight you. Because the code is a snapshot of the pre-2021 SymfonyBundles bundle, constraints are likely still around php ^7.4 and symfony/* ^4.4|^5.0. Verify with composer show --all before assuming; on Symfony 6/7 you may need --ignore-platform-reqs at best, and a fork at worst. The 1.0.0 tag does not imply a constraint bump — check, don't hope.
  2. Register the bundle in config/bundles.php (FilamentUno\JsonRequestBundle\...::class => ['all' => true]). There is no Flex recipe, so nothing is wired for you.
  3. Where to look first: the EventListener/ or Request/ directory. The whole bundle is a kernel.request listener that inspects Content-Type: application/json, decodes the body, and either rebinds it into the request bag or resolves a controller argument to a typed object. Read that one class before anything else — it is the entire product. With the upstream commit now named, you can also read the original source alongside it and diff; that is faster than reverse-engineering the fork.
  4. First use case: a POST /api/orders endpoint where you want OrderRequest $orderRequest type-hinted in the controller instead of Request $request and a pile of $request->toArray()['...'] ?? null.

Laravel equivalent of that first use case:

final class CreateOrderRequest extends FormRequest
{
    public function rules(): array
    {
        return [
            'customer_id' => ['required', 'integer', 'exists:customers,id'],
            'lines'       => ['required', 'array', 'min:1'],
            'lines.*.sku' => ['required', 'string'],
            'lines.*.qty' => ['required', 'integer', 'min:1'],
        ];
    }
}

public function store(CreateOrderRequest $request): OrderResource
{
    return new OrderResource($this->orders->create($request->validated()));
}

That is the bundle's job, done with framework-native tooling.

Implementation Patterns

The pattern the bundle is selling (and what to mirror):

  • Body → typed object at the boundary. Decode once, validate once, hand the controller a value object. Controllers never touch $request->request->get() or nested array access.
  • Listener/middleware-based transformation. In Symfony this is a kernel.request subscriber; in Laravel the direct analogue is a middleware that runs after TrimStrings/ConvertEmptyStringsToNull and rebinds the decoded payload:
public function handle(Request $request, Closure $next): Response
{
    if ($request->isJson() && $request->getContent()) {
        $decoded = json_decode($request->getContent(), true, 512, JSON_THROW_ON_ERROR);
        $request->replace(is_array($decoded) ? $decoded : []);
    }
    return $next($request);
}

Note $request->replace() writes into the input bag that validate() and input() read — do not write to $request->request (that is Symfony's parameter bag and Laravel's ParameterBag, and it is not what the validator consults).

  • DTO + validator. If you want the full version of what the bundle approximates, use spatie/laravel-data. It gives you typed properties, nested DataCollections, validation rules derived from attributes, and ::from($request). That is the modern, maintained answer to the problem this bundle was built for.

  • Validation error shape. Symfony bundles of this vintage typically return a 400 with a flat message or a ViolationList, or rely on the framework's 422. Laravel's default is 422 with {message, errors: {field: [..]}}. If you are porting an API contract, normalise this deliberately via an exception render hook rather than letting it drift. Since 1.0.0 ships no documented contract, the error shape is whatever the inherited code happens to do — read it, do not assume it.

  • Integration tips for a hybrid/migration context: put the decode in middleware rather than a controller base class, so artisan commands, queued jobs, and console-scheduled HTTP calls all see the same shape. Keep the DTO constructor strict (readonly, no nullable defaults for required fields) so a missing key throws loudly instead of becoming null three layers down.

  • If you are auditing the Symfony side specifically: pin the dependency to the exact tag, then diff against upstream fa0e3d25 (git clone the SymfonyBundles repo, git diff fa0e3d25 <vendor path>). Anything that differs is the fork author's contribution and the only thing worth reviewing; the rest is code you can find documented in years-old blog posts.

Gotchas and Tips

  • A new tag is not a revival. v1.0.0 re-releases 2020 code with a one-line note. There are no listed fixes, no PHP 8.x/Symfony 6+ support statement, no test suite mentioned, no issue triage. Do not read "1.0.0" as "stable" or "maintained" — read it as "the author pinned their starting point". Do not put this in a production dependency graph on the strength of the tag alone.
  • Bundle ≠ package. Symfony bundles use Bundle subclasses and DependencyInjection/Extension; Laravel uses ServiceProvider. There is no php artisan vendor:publish, no facade, no container alias. Any tutorial you find for this will be Symfony-flavoured and half of it will not translate.
  • Silent no-ops on content type. This class of bundle keys off Content-Type: application/json. application/merge-patch+json, application/vnd.api+json, or a client that forgets the header will bypass the listener entirely and your controller gets an empty payload — usually surfacing as a "required field missing" validation error that looks like a client bug. Test with curl -H 'Content-Type: application/json' --data '{"..."}', not with Postman's default form mode.
  • Empty body vs {} vs null. json_decode('') returns null, not []. Guard it, or every GET/DELETE that happens to share the middleware blows up. Also decide explicitly whether a top-level JSON scalar or array is a validation error — most naive decoders accept "[1,2,3]" and then confuse the validator.
  • JSON depth and size. Default json_decode depth is 512; deeply nested payloads fail with JSON_ERROR_DEPTH and it will look like a validation failure. Use JSON_THROW_ON_ERROR and catch JsonException into a 400 before validation ever runs.
  • Debugging. You cannot step into a 2020 bundle and get sane behaviour on modern PHP. If you must audit it, read the listener registration and its priority — a listener that runs before or after Symfony's own body parsing produces wildly different results, and a bundle that re-parses an already-parsed request is a common source of "works on one route, not the other". In Laravel, Telescope or a Log::debug($request->all()) at the top of the middleware tells you instantly whether the rebind happened.
  • Extension points, if you fork it: the useful seams are the decoder (swap in a streaming or camel-casing decoder) and the exception/error renderer. Both are small enough to own outright; do not fork the whole bundle to get them. Given v1.0.0 adds no extension API of its own, your fork should target the upstream commit, not this repo.
  • The honest recommendation, unchanged: skip the dependency, take the design. Middleware to normalise JSON input + FormRequest (or spatie/laravel-data for DTOs) + a consistent 422 error shape covers 100% of what this bundle does, on a supported framework, with a maintenance story. If you inherit a codebase already using it, budget for a migration rather than a version bump — an archived Symfony 5 bundle re-tagged as 1.0.0 is a liability, not a convenience.
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.
3mdikram/worldmoneywords
snowsoft/config
itmosoft/laravel-subscriptions
larva/laravel-ai-qwen
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