Laravel Queues allow you to delay a time-consuming task until a later time. By delaying the time-consuming task, you can improve the performance of the Laravel application significantly.
In this post, we will discuss Laravel Queues which is one of the best features of the Laravel framework. So let’s dive in.
Laravel Queues
Laravel
Queues provide integration of a variety of different queue backends
like Beanstalkd, Amazon SQS, Redis, synchronous (sync) and database. You
can find the queue configurations in the config/queue.php
file. In this file, we will define the connection’s configurations for each queue drivers. You can check the official documentation for more details.
Requirements
We will need a working Laravel Application to complete this tutorial. You can start a new Laravel project by running below command in terminal.
composer create-project laravel/laravel LaravelQueuesTutorial
In this post’s example, we are going to send emails from our application using queues. As we know, sending emails is a time-consuming task, so I’m going to use sending email as an example.
I alreay wrote an article on the Laravel Mailable which will help you to understand how to send an email in Laravel application.
Database Setup for Laravel Queues
We will use the database driver to process our queues, but you can use Amazon SQS or Redis if you have that setup already. I will stick to database.
Before using the Laravel Queues, we need to make a jobs
table in the database to store all queues. Laravel provides the table
creation command out of the box, so go to your terminal and run the
below command.
php artisan queue:table
This command will create a migration file in the database/migrations
folder. The newly created file will contain the schema for the jobs table which we need to process the queues.
use Illuminate\Support\Facades\Schema; use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Migrations\Migration; class CreateJobsTable extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::create('jobs', function (Blueprint $table) { $table->bigIncrements('id'); $table->string('queue')->index(); $table->longText('payload'); $table->unsignedTinyInteger('attempts'); $table->unsignedInteger('reserved_at')->nullable(); $table->unsignedInteger('available_at'); $table->unsignedInteger('created_at'); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::dropIfExists('jobs'); } }
Now it’s time to run the migrate command which will create the jobs
table in database. Run below command to migrate:
php artisan migrate
Once your database is updated with migrate command, you will find the newly created table called jobs
in the database.
Now we need to update the current queue drive in our environment file. Open .env
file and change the queue drive to the database like below.
QUEUE_DRIVER=database
Creating Mail And the View For Email
Next, we need to create a Laravel Mail which will just return a simple view with a welcome message. Run the following command to create a mail.
php artisan make:mail WelcomeEmail
Once the above command finishes, a new folder with name Mail along with a WelcomeEmail class file will be generated in the app folder.
You can read more hrer about Laravel Mailable.
namespace App\Mail; use Illuminate\Bus\Queueable; use Illuminate\Mail\Mailable; use Illuminate\Queue\SerializesModels; use Illuminate\Contracts\Queue\ShouldQueue; class WelcomeEmail extends Mailable { use Queueable, SerializesModels; /** * Create a new message instance. * * @return void */ public function __construct() { // } /** * Build the message. * * @return $this */ public function build() { return $this->view('mail.welcome'); } }
Next, we will update the build()
method so it can return our email view mail.welcome
.
Creating Email Template
For creating a email template, create a new folder inside views folder with name mail and then create a new file called welcome.blade.php
.
This file will container the following simple template:
<h1>Welcome To Our App</h1> <p>You are welcome to our platform.</p>
The view of the email is now complete, next we will create a new queue that will send this email.
Create Queue Job
Now, run the below command to generate a new queue job.
php artisan make:job SendWelcomeEmail
When you run this command, a new folder with name Jobs will be created inside app folder along with the SendWelcomeEmail job class.
namespace App\Jobs; use Illuminate\Bus\Queueable; use Illuminate\Queue\SerializesModels; use Illuminate\Queue\InteractsWithQueue; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Foundation\Bus\Dispatchable; class SendWelcomeEmail implements ShouldQueue { use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; /** * Create a new job instance. * * @return void */ public function __construct() { // } /** * Execute the job. * * @return void */ public function handle() { // } }
Now we will update this class to send our email. Firstly we need to add the Mail and SendWelcomeEmail namespaces in it.
use Mail; use App\Mail\WelcomeEmail;
Next, we need to setup email sending process inside the handle()
method.
/** * Execute the job. * * @return void */ public function handle() { $email = new WelcomeEmail(); Mail::to('info@larashout.com')->send($email); }
In handle function we have created a new instance of WelcomeEmail and used the Mail facade to send the email. Simple enough.
Our queue job is ready now to be tested. Normally, in a real-world scenario, we would like to dispatch this job within a controller when a certain action is completed. Like when a new user registers on our website we want to send email using the queue job.
I want to keep
this tutorial simple just to prove the concept. So I will create a new
route and controller for testing this job. When we will visit that route
a new job will be created in the jobs
table and will be processed on the time we specify.
Setup Route
For testing, you will need to add the below route in your routes/web.php
file.
Route::get('test-email', 'JobController@processQueue');
Create Controller
Now, we will create a new controller named JobController which will have a processQueue
method to dispatch the queue. Run below artisan command to generate this controller.
php artisan make:controller JobController
Now update your JobController with below code to process the queue.
namespace App\Http\Controllers; use Illuminate\Http\Request; use App\Jobs\SendWelcomeEmail; class JobController extends Controller { /** * Handle Queue Process */ public function processQueue() { $emailJob = new SendWelcomeEmail(); dispatch($emailJob); } }
Now if you visit /test-email
, a new job will insereted in the jobs table.
Running Queue Worker
The last thing to process this queue, you have to start the process of jobs by running below command in the terminal and leave it running.
php artisan queue:work