DEV Community

Cover image for How to enable Gzip compression in Laravel while hosting on AWS Lambda
Nitish Kumar for Noetic

Posted on

How to enable Gzip compression in Laravel while hosting on AWS Lambda

As I came across AWS Lambda Serverless services, it intrigued me and I wanted to learn more about its features.

Since my background is in PHP development and there were no platforms available to host PHP environments, it made sense to adopt Lambda into our development.

It’s a developer’s dream, not having to worry about scaling the cloud infrastructure, hefty bills, and offers low maintenance to boot.

Gradually, I learned about bref, a package that made it easy to host your PHP application on serverless. I started working on this package, finding the documentation and tutorials online. I successfully hosted my Laravel application on Lambda.

I came across various challenges during deployments.

A few days back, I was trying to fix my website from an SEO perspective, while doing a technical audit of my website, I came across a compression issue with my website. All the crawlers were asking to use a compression mechanism in my responses.

Digging deeper, I learned that AWS doesn't have compression enabled for its HTTP APIs. I spoke to the AWS support team and they asked me to implement a few changes in response, which will enable binary support for lambda response, AWS expects its response should have below attributes in response:

"body": gzippedResponse.toString("base64"),
"isBase64Encoded": true,
"statusCode": 200,
"headers": {
   "Content-Encoding": "gzip"
}
Enter fullscreen mode Exit fullscreen mode

I wanted to take the same approach with my Laravel application. I found one article about Gzip compression with Laravel Vapor, since I wasn't using Vapor, I had to research and implement in my own tech stack.

The documentation I found was easy to follow and helped me make the changes to my app. Now when I run my app, it works perfectly!

I configured my serverless.yml file with:

provider:
    # ...
    apiGateway:
        binaryMediaTypes:
            - '*/*'
    environment:
        BREF_BINARY_RESPONSES: '1'
Enter fullscreen mode Exit fullscreen mode

Then I made middleware as mentioned in the article:

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;

class GzipEncodeResponse
{
    public function handle(Request $request, Closure $next)
    {
        $response = $next($request);

        if (in_array('gzip', $request->getEncodings()) && function_exists('gzencode')) {
            $response->setContent(gzencode($response->getContent(), 9));
            $response->headers->add([
                'Content-Encoding' => 'gzip',
                'X-Vapor-Base64-Encode' => 'True',
            ]);
        }
        return $response;
    }
}
Enter fullscreen mode Exit fullscreen mode

And then added this middleware in my kernel.php file:

protected $middlewareGroups = [
    'web' => [
        \App\Http\Middleware\EncryptCookies::class,
        \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
        \Illuminate\Session\Middleware\StartSession::class,
        \Illuminate\View\Middleware\ShareErrorsFromSession::class,
        \App\Http\Middleware\VerifyCsrfToken::class,
        \Illuminate\Routing\Middleware\SubstituteBindings::class,
        \App\Http\Middleware\GzipEncodeResponse::class,
    ],

    'api' => [
        'throttle:api',
        \Illuminate\Routing\Middleware\SubstituteBindings::class,     
    ],
];
Enter fullscreen mode Exit fullscreen mode

And did serverless deploy

Everything was working perfectly as expected. I achieved my gzip compression in my HTTP APIs

Latest comments (0)