Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Call Laravel controller action from Job handler, with dependency injections

Tags:

php

laravel

I have middleware that put task in a queue, passing $actionName and GET/POST parameters to Job constructor. This code:

$actionName = last(explode('@', $request->route()->getActionName()));
$arguments = $request->query->all();
$job = new HandleApiRequest($actionName, $arguments);
dispatch($job);

And then, in Job handler, I'd like to call Controller method with passed arguments(arguments initialized in Job constructor, don't worry about that). Here is a code:

$data = app()->call(ApiController::class . '@' . $this->method, $this->arguments);

The problem, is that I cannot use Request object(Illuminate\Http\Request) in called Controller and it's services. Seems like controller goes to infinite loop, and in it services it's just empty. Then I see this logs in console from worker:

[Illuminate\Contracts\Container\BindingResolutionException]                                                      
  Target [App\Http\Requests\Request] is not instantiable while building [App\Http\Controllers\Api\ApiController].  

The question is, how can I properly initialize Request object in Job handler?

Thanks!

like image 419
Bushikot Avatar asked May 23 '16 17:05

Bushikot


People also ask

How do you call a controller in Laravel?

use App\Http\Controllers\UserController; Route::get('/user/{id}', [UserController::class, 'show']); When an incoming request matches the specified route URI, the show method on the App\Http\Controllers\UserController class will be invoked and the route parameters will be passed to the method.

How do you call a controller job?

To call the job from your controller you need to inject quartzScheduler then call the triggerNow function with reference of your job class like written above in the controller. Note: Ensure that the package structure of your job class must be same as your controller class in order to call the job from controller.

How do you call a controller inside a view in Laravel?

$varbl = App::make("ControllerName")->FunctionName($params); to call a controller function from a my balde template(view page).


1 Answers

The solution was to inject Request object into handler method, and fill it with data passed from middleware:

class HandleApiRequest extends Job implements ShouldQueue
{
    use InteractsWithQueue, SerializesModels;

    private $method;
    private $arguments;

    public function __construct(string $method, array $arguments)
    {
        $this->method = $method;
        $this->arguments = $arguments;


    }

    public function handle(ErrorService $error_service, Request $request)
    {
        /*
         * Fill our empty request object with arguments passed by middleware.
         * It's later will be used in controller and services.
         */
        $request->query->add($this->arguments);
        $data = app()->call(ApiController::class . '@' . $this->method);

        //use $data here
    }

}

Hope it will be useful for somebody, otherwise I'll delete this whole thread later.

like image 109
Bushikot Avatar answered Oct 03 '22 16:10

Bushikot