Lazhar
Lazhar

Reputation: 1458

How to send gzipped json response from Google Cloud Functions?

My JSON responses in one of my Google Cloud Functions could be reduced up to 70-80% in size if I respond using gzip compression.

How can I send a compressed json response from my Functions (trigger via http(s))?

This would also mean I would save on a lot of network expenses with google cloud platform, and a faster loading of the data for mobile consumers of the data.

I've tried using the zlib native module but no luck...

if (req.get('Accept-Encoding') && req.get('Accept-Encoding').indexOf('gzip') > -1) {

    interpretation.gzip = true;

    const zlib = require('zlib');

    res.set('Content-Type', 'text/plain');
    res.set('Content-Encoding', 'gzip');

    zlib.gzip(JSON.stringify(interpretation), function (error, result) {
        if (error) throw error;
        res.status(200).send(result);
    })

} else {
    interpretation.gzip = false;
    res.status(200).send(interpretation);
}

In Postman, the size of the response is the same, the content-type has changed, but there is no Content-Encoding header set in the response...

At the top (white background) is the my request's headers. Works well, and the header is received by my application. The response headers miss my Content-Encoding.

Upvotes: 7

Views: 5618

Answers (3)

Ronnie Smith
Ronnie Smith

Reputation: 18555

Expressjs Production best practices: performance and reliability says below, which could be adapted for basic Node.js. They use the popular compression package available on NPM.

Use gzip compression

Gzip compressing can greatly decrease the size of the response body and hence increase the speed of a web app. Use the compression middleware for gzip compression in your Express app. For example:

var compression = require('compression')
var express = require('express')
var app = express()
app.use(compression())

Upvotes: -1

Manuel Perez Heredia
Manuel Perez Heredia

Reputation: 2357

Look at the App Engine FAQ, specifically the answer to the question "How do I serve compressed content?":

....To force gzipped content to be served, clients may supply 'gzip' as the value of both the Accept-Encoding and User-Agent request headers. Content will never be gzipped if no Accept-Encoding header is present...

Also, in this group post there's an example of how to send a request with Cloud Functions using the combination of Accept-Encoding, User-Agent:

curl -v "https://us-central1-<project>.cloudfunctions.net/test" -H "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36" -H "Accept-Encoding: gzip"

Upvotes: 5

Damaged Organic
Damaged Organic

Reputation: 8467

You can probably try to use zlib module to handle compression and set an appropriate encoding to the response:

exports.helloWorld = function helloWorld(req, res) {
  const zlib = require('zlib');

  // Obtain JSON stream from your source...

  res.status(200);

  res.set('Content-Type', 'text/plain');
  res.set('Content-Encoding', 'gzip');

  json.pipe(zlib.createGzip()).pipe(res);
};

Of course, it's required to first check whether client accepts gzip. Also, using zlib encoding can be expensive, and the results ought to be cached.

Upvotes: 0

Related Questions