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

Request Data Bundle Laravel Package

bilyiv/request-data-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation

    composer require bilyiv/request-data-bundle
    

    Register the bundle in config/app.php under extra.bundles if not auto-discovered.

  2. Configure Prefix Update config/packages/bilyiv_request_data.yaml (or define in config/services.yaml):

    request_data:
        prefix: App\RequestData
    
  3. 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];
        }
    }
    
  4. 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
        }
    }
    

Implementation Patterns

Core Workflow

  1. Define Request Data Classes

    • Place classes in App\RequestData (or configured prefix).
    • Implement FormatSupportableInterface to declare supported formats (e.g., JSON, FORM, XML).
    • Properties auto-populate from request data (query params, body, etc.).
  2. Controller Integration

    • Inject RequestDataFactory to create typed request objects.
    • Example:
      $requestData = $this->requestDataFactory->create(MyRequestData::class);
      // Validate or process $requestData->property
      
  3. Middleware for Global Usage

    • Create middleware to attach request data to the request object:
      public function handle($request, Closure $next)
      {
          $request->setRequestData($this->requestDataFactory->create(MyRequestData::class));
          return $next($request);
      }
      
    • Access via $request->requestData in controllers or services.
  4. Validation Integration

    • Use with Laravel’s validator:
      $validator = Validator::make($request->requestData, [
          'email' => 'required|email',
      ]);
      
  5. Event Dispatching

    • Listen for request_data.finished event to react to parsed data:
      Event::listen('request_data.finished', function ($event) {
          // $event->getRequestData() returns the parsed object
      });
      

Advanced Patterns

  • 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
    }
    

Gotchas and Tips

Pitfalls

  1. Format Mismatch Exceptions

    • If the request’s Content-Type or method doesn’t match getSupportedFormats(), the factory throws UnsupportedFormatException.
    • Fix: Ensure formats align with expected input (e.g., Accept: application/json for JSON format).
  2. Property Overwriting

    • Properties are populated in declaration order (PHP 7.0+). Later properties may overwrite earlier ones if keys collide.
    • Tip: Use explicit property types (e.g., public ?string $nullableField = null) to avoid unintended overwrites.
  3. Query Parameter Normalization

    • Query params are lowercased by default (e.g., ?Name=John → $data->name).
    • Tip: Override normalizeKey() in your class to customize:
      protected static function normalizeKey(string $key): string
      {
          return strtolower(preg_replace('/[^a-zA-Z0-9]/', '_', $key));
      }
      
  4. XML Parsing Quirks

    • XML parsing relies on SimpleXMLElement. Nested structures may not map cleanly to flat properties.
    • Tip: Use XmlMap trait or custom logic in getSupportedFormats() to handle complex XML.
  5. Circular Dependencies

    • Avoid circular references between request data classes (e.g., A references B, which references A).
    • Fix: Use lazy loading or interfaces to decouple dependencies.

Debugging Tips

  1. Enable Verbose Logging Configure the bundle to log parsing steps:

    request_data:
        debug: true
    

    Logs appear in storage/logs/laravel.log.

  2. Inspect Raw Data Access raw request data before parsing:

    $rawData = $this->requestDataFactory->getRawData(MyRequestData::class);
    
  3. Test Format Detection Manually trigger format checks:

    $this->requestDataFactory->supportsFormat(MyRequestData::class, Formats::JSON);
    

Extension Points

  1. Custom Format Parsers Extend Bilyiv\RequestDataBundle\Parsers\AbstractParser to add support for new formats (e.g., Formats::PROTOBUF).

  2. 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']
    
  3. 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']));
    });
    
  4. Override Default Behavior Replace the factory or parsers entirely by binding interfaces in AppServiceProvider:

    $this->app->bind(
        RequestDataFactory::class,
        CustomRequestDataFactory::class
    );
    
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.
coleus/frame
thtg88/journalism
filagora/filagora-ai-forums
rlacerda83/query-parser
socialdept/atp-orm
cboxdk/laravel-assistant-client
socialdept/atp-resolver
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings