How to use a Middleware on a Laravel Job

In this example, we will learn how to create a middleware class to use on Laravel jobs. You can use a middleware to run any task using the data passed to Laravel job before executing the handle() method of the Laravel job class.

Example

Lets create a Laravel web application that uses Laravel Jobs and Middleware. For this example, we will create a middleware to log the status of the Laravel job before running. You can use middleware for throttling, rate limiting, logging, etc. For the simplicity of this example, we are going to log information in the Laravel log file.

Setup Laravel project with a Laravel Job

Create Laravel project using the Laravel documentation. After that create below files.

Lets create a sample Laravel job called ProcessData.

php artisan make:job ProcessData

Now modify above created job class to accept data. For the simplicity I am accepting simple string when dispatching this job class. Then add log information in the handle method to ensure handle() method execute correctly while dispatching the job.

namespace App\Jobs;

use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Queue\Queueable;
use Illuminate\Support\Facades\Log;

class ProcessData implements ShouldQueue
{
    use Queueable;

    /**
     * Create a new job instance.
     */
    public function __construct(public string $data) { }

    /**
     * Execute the job.
     */
    public function handle(): void
    {
        Log::info("Running job handle method");
    }
}

Next execute above created Laravel Job when the application received a get request to root domain. Lets modify web.php to accept get request on root domain and dispatch above created job.

use App\Jobs\ProcessData;
use Illuminate\Support\Facades\Route;
use Illuminate\Support\Facades\Log;

Route::get('/', function () {
    Log::info('Received a get request on root domain');
    ProcessData::dispatch("Data passed to job");      
});

Create middleware class

It is time to add a middleware to above ProcessData job class. By default, there is no any reserved location to store middleware classes for jobs. So, I am using Jobs folder to store all middleware classes related jobs. First create a folder called “Middleware” inside the “Jobs” folder. Then create LogJobStatus middleware class inside the Middleware folder.

About Job Middleware Class

  1. Class Name can have any desired name. Does not need to have prefixes and postfixes.
  2. Must have handle() method inside the middleware class.
  3. Handle() method should accept two parameters. First one should be the Laravel Job object. Second parameter is a closure used to continue job execution process.

Below shows a sample example of LogJobStatus job middleware.

<?php
namespace App\Jobs\Middleware;

use Closure;
use Illuminate\Support\Facades\Log;

/**
 * Log status of the job to Laravel logs
 */
class LogJobStatus{

  public function handle(Object $job, Closure $next):void
  {
      Log::info("Logging job status. Middleware is running...");
      Log::info("logging data passed to middleware: ". $job->data);
      //Your code here.
      $next($job);
  }
}

Bind created middleware with Laravel job class

Middleware binding with job classes happen within the job class. Create a middleware() method inside the job class and return used middleware class instances in a array.

<?php

namespace App\Jobs;

use App\Jobs\Middleware\LogJobStatus;
use Illuminate\Foundation\Queue\Queueable;
use Illuminate\Support\Facades\Log;

class ProcessData implements ShouldQueue
{
    use Queueable;

    /**
     * Create a new job instance.
     */
    public function __construct(public string $data)
    {
        //
    }

    /**
     * Execute the job.
     */
    public function handle(): void
    {
        Log::info("Running job handle method");
    }

    public function middleware():array
    {
        return [new LogJobStatus];
    }
}

Testing the result

First run Laravel web application.

php artisan serve

Then run queue worker

php artisan queue:work

Send a get request to application root domain and check Laravel logs file. You will see the order of execution. Middleware run before the job.

[2024-12-14 07:04:32] local.INFO: Received a get request on root domain  
[2024-12-14 07:04:33] local.INFO: Logging job status middleware is running...  
[2024-12-14 07:04:33] local.INFO: Data passed to job  
[2024-12-14 07:04:33] local.INFO: Running job handle method