Installation
composer require bilyiv/request-data-bundle
Register the bundle in config/app.php under extra.bundles if not auto-discovered.
Configure Prefix
Update config/packages/bilyiv_request_data.yaml (or define in config/services.yaml):
request_data:
prefix: App\RequestData
First Use Case
Create a request data class (e.g., app/RequestData/CreateUserRequestData.php):
namespace App\RequestData;
use Bilyiv\RequestDataBundle\Interfaces\FormatSupportableInterface;
use Bilyiv\RequestDataBundle\Enums\Formats;
class CreateUserRequestData implements FormatSupportableInterface
{
public $name;
public $email;
public static function getSupportedFormats(): array
{
return [Formats::JSON, Formats::FORM];
}
}
Inject and Use in Controller
use App\RequestData\CreateUserRequestData;
use Bilyiv\RequestDataBundle\Services\RequestDataFactory;
class UserController
{
public function __construct(private RequestDataFactory $requestDataFactory) {}
public function store()
{
$data = $this->requestDataFactory->create(CreateUserRequestData::class);
// $data->name, $data->email are now populated
}
}
Define Request Data Classes
App\RequestData (or configured prefix).FormatSupportableInterface to declare supported formats (e.g., JSON, FORM, XML).Controller Integration
RequestDataFactory to create typed request objects.$requestData = $this->requestDataFactory->create(MyRequestData::class);
// Validate or process $requestData->property
Middleware for Global Usage
public function handle($request, Closure $next)
{
$request->setRequestData($this->requestDataFactory->create(MyRequestData::class));
return $next($request);
}
$request->requestData in controllers or services.Validation Integration
$validator = Validator::make($request->requestData, [
'email' => 'required|email',
]);
Event Dispatching
request_data.finished event to react to parsed data:
Event::listen('request_data.finished', function ($event) {
// $event->getRequestData() returns the parsed object
});
Dynamic Class Resolution
Use RequestDataFactory::createFromRequest() to auto-detect classes based on route names or custom logic:
$this->requestDataFactory->createFromRequest('User\\Create\\RequestData');
Custom Format Support
Extend FormatSupportableInterface to add new formats (e.g., Formats::GRAPHQL):
public static function getSupportedFormats(): array
{
return [Formats::JSON, Formats::GRAPHQL];
}
Nested Request Data Reference other request data classes as properties:
class UpdateUserRequestData
{
public $userId;
public $profileData; // Auto-instantiated as ProfileRequestData
}
Format Mismatch Exceptions
Content-Type or method doesn’t match getSupportedFormats(), the factory throws UnsupportedFormatException.Accept: application/json for JSON format).Property Overwriting
public ?string $nullableField = null) to avoid unintended overwrites.Query Parameter Normalization
?Name=John → $data->name).normalizeKey() in your class to customize:
protected static function normalizeKey(string $key): string
{
return strtolower(preg_replace('/[^a-zA-Z0-9]/', '_', $key));
}
XML Parsing Quirks
SimpleXMLElement. Nested structures may not map cleanly to flat properties.XmlMap trait or custom logic in getSupportedFormats() to handle complex XML.Circular Dependencies
A references B, which references A).Enable Verbose Logging Configure the bundle to log parsing steps:
request_data:
debug: true
Logs appear in storage/logs/laravel.log.
Inspect Raw Data Access raw request data before parsing:
$rawData = $this->requestDataFactory->getRawData(MyRequestData::class);
Test Format Detection Manually trigger format checks:
$this->requestDataFactory->supportsFormat(MyRequestData::class, Formats::JSON);
Custom Format Parsers
Extend Bilyiv\RequestDataBundle\Parsers\AbstractParser to add support for new formats (e.g., Formats::PROTOBUF).
Request Data Transformers
Implement Bilyiv\RequestDataBundle\Interfaces\TransformerInterface to modify parsed data:
class UppercaseTransformer implements TransformerInterface
{
public function transform($data, $class)
{
foreach ($data as $key => $value) {
$data->$key = strtoupper($value);
}
return $data;
}
}
Register in services:
services:
Bilyiv\RequestDataBundle\Services\RequestDataFactory:
arguments:
$transformers: ['@uppercase_transformer']
Event Customization
Subscribe to request_data.before_parse to pre-process data or request_data.after_parse to post-process:
Event::listen('request_data.before_parse', function ($event) {
$event->setData(array_merge($event->getData(), ['default' => 'value']));
});
Override Default Behavior
Replace the factory or parsers entirely by binding interfaces in AppServiceProvider:
$this->app->bind(
RequestDataFactory::class,
CustomRequestDataFactory::class
);
How can I help you explore Laravel packages today?