Setup Queue with Serverless Laravel using bref
Tags: serverless, laravel, queue, sqs
Published: 2020-08-10 13:49:54

---
title: Setup Queue with Serverless Laravel using bref
published: true
description: Setup AWS SQS(Simple Queue Service) with Serverless Laravel application using bref 
tags: serverless, laravel, queue, sqs
cover_image: https://dev-to-uploads.s3.amazonaws.com/i/yislevvlt7y07ynlmcvq.png
---
This tutorial assumes you already have a Serverless Laravel setup in place, if not then you can follow this tutorial **"[Deploy Serverless Laravel](https://dev.to/chandreshhere/deploy-serverless-laravel-application-using-bref-cp2)"**

Let's see how we can setup AWS SQS with our Serverless Laravel Application.

If you would like to see me doing it then you can watch it here as well.

{% youtube qThgfivpmd0 %}

Let’s Start

First thing we need to do is pull in this package in your laravel application using composer.

```bash
composer require bref/laravel-bridge
```

If you followed the previous tutorial then you should already be having **serverless.yml** file in your Laravel application directory. Make sure it looks something like this:

```bash
service: laravel-starter-serverless

provider:
    name: aws
    region: ap-south-1
    runtime: provided

plugins:
    - ./vendor/bref/bref

package:
  exclude:
    - node_modules/**
    - public/storage
    - resources/assets/**
    - storage/**
    - tests/**

functions:
    website:
        handler: public/index.php
        timeout: 28 # in seconds (API Gateway has a timeout of 29 seconds)
        layers:
            - ${bref:layer.php-73-fpm}
        events:
            -   http: 'ANY /'
            -   http: 'ANY /{proxy+}'
    artisan:
        handler: artisan
        timeout: 120 # in seconds
        layers:
            - ${bref:layer.php-73} # PHP
            - ${bref:layer.console} # The "console" layer
    worker:
        handler: worker.php
        layers:
          - ${bref:layer.php-73}
        events:
          # Declares that our worker is triggered by jobs in SQS
            - sqs:
                arn: !GetAtt AlertQueue.Arn
                # If you create the queue manually, the line above could be:
                # arn: 'arn:aws:sqs:us-east-1:1234567890:my_sqs_queue'
                # Only 1 item at a time to simplify error handling
                batchSize: 1

resources:
  Resources:
    # The SQS queue
    AlertQueue:
      Type: AWS::SQS::Queue
      Properties:
        RedrivePolicy:
          maxReceiveCount: 3 # jobs will be retried up to 3 times
          # Failed jobs (after the retries) will be moved to the other queue for storage
          deadLetterTargetArn: !GetAtt DeadLetterQueue.Arn

    # Failed jobs will go into that SQS queue to be stored, until a developer looks at these errors
    DeadLetterQueue:
      Type: AWS::SQS::Queue
      Properties:
        MessageRetentionPeriod: 1209600 # maximum retention: 14 days
```


Here we are creating a new lambda function which will act as a worker for our queue and will be invoked by a new job event from SQS.

We are also creating two queues in SQS, first one will act as a queue for processing jobs and second will be used for failed jobs.

Now, Create a new file **worker.php** inside application directory which will handle SQS event in AWS lambda.

```php
<?php declare(strict_types=1);

use Bref\LaravelBridge\Queue\LaravelSqsHandler;
use Illuminate\Foundation\Application;

require __DIR__ . '/vendor/autoload.php';
/** @var Application $app */
$app = require __DIR__ . '/bootstrap/app.php';

$kernel = $app->make(Illuminate\Contracts\Console\Kernel::class);
$kernel->bootstrap();

return $app->makeWith(LaravelSqsHandler::class, [
    'connection' => 'sqs', // this is the Laravel Queue connection
    'queue' => getenv('SQS_QUEUE'),
]);
```

Now we need to make a small change in **config/queue.php** file to add AWS session token. This may not be an issue in the latest version of laravel.

```php
       'sqs' => [
            ...
            'token' => env('AWS_SESSION_TOKEN'),
        ],
```

Set two environment variables in **.env** file.

```bash
QUEUE_CONNECTION=sqs
AWS_DEFAULT_REGION=ap-south-1
```

Now before we deploy our code we need to provide permission to AWS IAM user which you created for deploying Serverless Laravel.

So login into your AWS account and go to IAM. 

![IAM](https://dev-to-uploads.s3.amazonaws.com/i/513gkyaumwx2hcmqpy0p.png)

Click on users link and then Select your user.

![Edit Policy](https://dev-to-uploads.s3.amazonaws.com/i/imxuy0uvkw5rxbe6fq8z.png)

Select the policy and Click on Edit policy

Click on add additional permission.

Choose SQS in service.

I’m giving it full access to SQS but you can selectively give it READ and WRITE access.

Select all resource in resources.

Click on review policy.

If you get a popup asking for deleting older version of policy  then click on delete version and save.

and That’s it.

Type 
```bash
serverless deploy
```

and this will take care of setting up your queue and lambda function.

If you get internal server error then try running:

```bash
php artisan config:cache
#to build all cache files
```

And then 
```bash
php artisan config:clear
#to remove config cache file
```

Try again and this time you should see the welcome screen. Try sending a job to queue from your laravel application and you will see that that queue jobs are being processed instantly.

One thing to note here is this **/dev/** prefix before every route.

This is because of AWS API Gateway which works in stages. 
If you want to remove this then you will have to setup a custom domain for your application on AWS or you will need to take this into account before using any route.

If you have followed till now you should be having a working queue with your serverless laravel application.

Hope you find this useful!

{% github https://github.com/csinghdev/laravel-starter-serverless %}