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

Symfony Custom Request Laravel Package

dittto/symfony-custom-request

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation Add the package via Composer:

    composer require dittto/symfony-custom-request
    

    If the package isn't on Packagist, add the GitHub repo to composer.json:

    "repositories": [
        {
            "type": "vcs",
            "url": "https://github.com/dittto/symfony-custom-request"
        }
    ]
    
  2. Register the Bundle Add the bundle to AppKernel.php (or Kernel.php in Symfony 4+):

    new Dittto\CustomRequestBundle\DitttoCustomRequestBundle(),
    
  3. Create Your First Custom Request Define a custom request class (e.g., src/Request/TestRequest.php):

    use Dittto\CustomRequestBundle\Request\CustomRequest;
    
    class TestRequest extends CustomRequest
    {
        public function validate()
        {
            return $this->query->has('token') && $this->query->get('token') === 'allowed';
        }
    }
    
  4. Use in Controller Inject the custom request into your controller:

    use App\Request\TestRequest;
    
    class MyController extends AbstractController
    {
        public function index(TestRequest $request)
        {
            // Request is validated; proceed with confidence
        }
    }
    

First Use Case

Scenario: Validate a query parameter (token) before processing a request. Steps:

  1. Create TestRequest as shown above.
  2. Register it as a service (see Implementation Patterns).
  3. Use it in a controller to ensure the token is valid before proceeding.

Implementation Patterns

Workflows

  1. Service Registration Define custom requests as services in config/services.yaml (Symfony 4+) or app/config/services.yml:

    services:
        App\Request\TestRequest:
            arguments:
                $query: '@request_stack'
            tags: ['dittto.custom_request']
    
    • Key: Tag the service with dittto.custom_request for automatic validation.
  2. Dependency Injection

    • Inject custom requests into controllers or other services:
      public function __construct(TestRequest $request) { ... }
      
    • Laravel-specific: Use constructor injection in controllers or bind the request in AppServiceProvider:
      public function register()
      {
          $this->app->bind(TestRequest::class, function ($app) {
              return new TestRequest($app['request']);
          });
      }
      
  3. Validation Logic Extend CustomRequest and override validate():

    public function validate()
    {
        // Example: Validate POST data + external API
        if (!$this->request->isMethod('post')) {
            return false;
        }
        $data = $this->request->request->all();
        if (empty($data['email'])) {
            return false;
        }
        // Call external service (e.g., via HTTP client)
        $apiResponse = $this->apiClient->validateEmail($data['email']);
        return $apiResponse['valid'];
    }
    
  4. Reusing Validation Logic

    • Shared Services: Inject services (e.g., UserRepository, ApiClient) into custom requests:
      class UserRequest extends CustomRequest
      {
          public function __construct(
              Request $request,
              UserRepository $userRepo
          ) {
              $this->userRepo = $userRepo;
              parent::__construct($request);
          }
      
          public function validate()
          {
              $user = $this->userRepo->find($this->query->get('id'));
              return $user && $user->isActive();
          }
      }
      
    • Register the service with dependencies:
      services:
          App\Request\UserRequest:
              arguments:
                  $userRepo: '@App\Repository\UserRepository'
              tags: ['dittto.custom_request']
      
  5. Controller Integration

    • Symfony: Use type-hinting in controller actions.
    • Laravel: Bind the request and inject it:
      public function show(UserRequest $request)
      {
          $userId = $request->query->get('id');
          // Proceed with validated data
      }
      

Integration Tips

  • Laravel-Specific:

    • Replace Symfony’s Request with Laravel’s Illuminate\Http\Request in custom requests:
      use Illuminate\Http\Request;
      
      class LaravelCustomRequest extends CustomRequest
      {
          public function __construct(Request $request) { ... }
      }
      
    • Bind the custom request in AppServiceProvider:
      $this->app->bind(LaravelCustomRequest::class, function ($app) {
          return new LaravelCustomRequest($app->make(Request::class));
      });
      
  • Validation Layers: Combine with Laravel’s built-in validation (e.g., Form Requests) for layered validation:

    // In a Form Request
    public function authorize() {
        return true; // Always pass
    }
    
    public function rules() {
        return [
            'email' => 'required|email',
        ];
    }
    
    // In CustomRequest
    public function validate() {
        $validator = Validator::make($this->request->all(), ['email' => 'required']);
        return !$validator->fails();
    }
    
  • Error Handling:

    • Throw exceptions or return false in validate().
    • Catch exceptions in controllers:
      try {
          $this->index($request);
      } catch (InvalidRequestException $e) {
          abort(400, $e->getMessage());
      }
      

Gotchas and Tips

Pitfalls

  1. Outdated Package:

    • Last release in 2016; may not work with modern Symfony/Laravel.
    • Workaround: Fork the repo and update dependencies (e.g., Symfony components).
  2. Service Registration:

    • Forgetting to tag services with dittto.custom_request will bypass validation.
    • Fix: Ensure all custom requests are tagged in services.yaml:
      tags: ['dittto.custom_request']
      
  3. Request Object Mismatch:

    • The package expects Symfony’s Request object. In Laravel, manually pass the Illuminate\Http\Request.
    • Fix: Extend the base class or mock the Symfony Request interface.
  4. Circular Dependencies:

    • Injecting controllers into custom requests creates circular dependencies.
    • Fix: Use services (e.g., repositories) instead of controllers.
  5. Validation Short-Circuiting:

    • If validate() returns false, the request stops processing.
    • Fix: Return early or use multiple validation steps with &&.

Debugging

  1. Validation Failures:

    • Add logging in validate():
      public function validate() {
          \Log::debug('Request data:', $this->request->all());
          return $this->query->get('token') === 'allowed';
      }
      
    • Check Laravel logs (storage/logs/laravel.log) or Symfony’s var/log/dev.log.
  2. Service Not Found:

    • Verify the service is registered and tagged:
      php bin/console debug:container App\Request\TestRequest
      
    • In Laravel, dump the service container:
      dd(app()->has('App\Request\TestRequest'));
      
  3. Request Object Issues:

    • Ensure the injected Request object matches the expected type (Symfony vs. Laravel).
    • Test: Dump the request class:
      \Log::debug(get_class($this->request));
      

Tips

  1. Reuse Validation Logic:

    • Extract common validation into base classes or traits:
      trait ValidatesToken {
          public function validateToken()
          {
              return $this->query->get('token') === 'allowed';
          }
      }
      
  2. Dynamic Validation:

    • Use dependency injection to fetch dynamic data (e.g., from a database):
      class ApiKeyRequest extends CustomRequest {
          public function __construct(Request $request, ApiKeyService $apiKeyService) {
              $this->apiKeyService = $apiKeyService;
              parent::__construct($request);
          }
      
          public function validate() {
              $key = $this->header('X-API-KEY');
              return $this->apiKeyService->isValid($key);
          }
      }
      
  3. Performance:

    • Cache validation results if the request is stateless (e.g., API tokens):
      public function validate() {
          return cache()->remember("token_{$this->query->get('token')}", 3600, function() {
              return $this->query->get('token') === 'allowed';
          });
      }
      
  4. Testing:

    • Mock custom requests in PHPUnit:
      $mockRequest = $this->createMock(CustomRequest::class);
      $mockRequest->method('validate')->will
      
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.
emuniq/filament-browser-notifications
syriable/filament-translator
hungnm28/livewire-form
wenprise/eloquent
crudly/encrypted
fadion/bouncy
cuci/prototurk-sdk
gos/pubsub-router-bundle
cuci/prototurk-sdk-symfony
clementtalleu/easyadmin-markdown-bundle
codeflextech/permission-manager
karnoweb/livewire-datepicker
sayedenam/sayed-dashboard
milito/query-filter
apiboxsym/user-bundle
apiboxsym/health-check-bundle
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui