Running Serverless Node.js on Google Cloud Functions

Google Cloud Functions is a service that allows you to run your code in the cloud. You don't need to manage server, just code for the application logic (serverless). It's also highly available and fault tolerant, as well as very automatically scales. There are some ways to trigger function execution, some of which are the result of integration with other Google Cloud services. In this tutorial, I'm going to show how to run serverless Node.js in Google Cloud Functions.

Preparation

1. Create or select a Google Cloud project

A Google Cloud project is required to use this service. Open Google Cloud console, then create a new project or select existing project

2. Enable billing for the project

Like other cloud platforms, Google requires you to enable billing for your project. If you haven't set up billing, open billing page.

3. Enable Cloud Functions API

To use an API, you must enable it first. Open this page to enable Cloud Functions API.

4. Set up service account for authentication

You need to install gcloud on your computer and get authenticated to access your account.

Writing a Function

First, create a folder for this project. Inside the folder, create a file with the following content.

index.js

  exports.helloWorld = (req, res) => res.send("Hello, World!");

Running Google Cloud Functions Emulator

Before running functions on the real Google Cloud servers, we can test whether the code works as expected by running Google Cloud Functions Emulator on your local machine.

  • First, you need to install the emulator using npm install -g @google-cloud/functions-emulator
  • Run it using functions start.
  • To deploy the helloWorld function we have created on the previous step, run functions deploy helloWorld --trigger-http
  • If the function successfully deployed, you will see a resource URL - open it to call the function

Deploying to Google Cloud Functions

Run the following command in order to deploy the functionn to Google Cloud Functions.

gcloud functions deploy helloAsync --trigger-http --project PROJECT_NAME

Below is the list of supported flags while running gcloud functions deploy command.

  gcloud functions deploy (NAME : --region=REGION)
        [--entry-point=ENTRY_POINT] [--memory=MEMORY] [--retry]
        [--runtime=RUNTIME] [--source=SOURCE] [--stage-bucket=STAGE_BUCKET]
        [--timeout=TIMEOUT] [--update-labels=[KEY=VALUE,...]]
        [--clear-env-vars | --env-vars-file=FILE_PATH
          | --set-env-vars=[KEY=VALUE,...]
          | --remove-env-vars=[KEY,...] --update-env-vars=[KEY=VALUE,...]]
        [--clear-labels | --remove-labels=[KEY,...]]
        [--trigger-bucket=TRIGGER_BUCKET | --trigger-http
          | --trigger-topic=TRIGGER_TOPIC
          | --trigger-event=EVENT_TYPE --trigger-resource=RESOURCE]
        [GCLOUD_WIDE_FLAG ...]

NAME is the ID of the function or fully qualified identifier for the function. Description for each flags is on the table below

Flag Description
--region=REGION The Cloud region for the function.
--entry-point=ENTRY_POINT Specify the name of the function that will be executed, overriding default behavior that executes function with the same name.
--memory=MEMORY Amount of memory the function can use. Allowed values are: 128MB, 256MB (default), 512MB, 1024MB, and 2048MB.
--retry If specified, then the function will be retried in case of a failure.
--runtime=RUNTIME The runtime in which to function runs. Choices:
  • nodejs6: Node.js 6 (default)
  • nodejs8: Node.js 8
  • python37: Python 3.7
--source=SOURCE Location of source code to deploy. Choices:
  • Source code in Google Cloud Storage (must be a .zip archive),
  • Reference to source repository
  • Local filesystem path (root directory of function source).
--stage-bucket=STAGE_BUCKET The name of the Google Cloud Storage bucket in which source code will be stored, when deploying a function from a local directory
--timeout=TIMEOUT The function execution timeout, e.g. 30s for 30 seconds. Default: 60s. Max: 540s.
--update-labels=[KEY=VALUE,...] A list of label KEY=VALUE pairs to update (upsert). Keys must start with a lowercase character. Keys and values can  only contain underscores (_), hyphens (-), numbers, and lowercase characters.
--clear-env-vars Remove all environment variables.
--env-vars-file=FILE_PATH Path to a local YAML file with definitions for all environment variables. It will remove all existing environmnt variables first.
--set-env-vars=[KEY=VALUE,...] List of key-value pairs to set as environment variables. It will remove all existing environmnt variables first.
--remove-env-vars=[KEY,...] The Cloud region for the function.
--update-env-vars=[KEY=VALUE,...] List of environment variables to be removed.
--clear-labels Removes all labels. If --update-labels is also specified then --clear-labels is applied first.
--remove-labels=[KEY,...] List of label keys to remove.
--trigger-bucket=TRIGGER_BUCKET Name of Google Cloud Storage bucket. The function will be triggered everytime change of files in the bucket occurs.
--trigger-http Function will be assigned with an endpoint and will be triggered everytime HTTP request call to the endpoint occurs.
--trigger-topic=TRIGGER_TOPIC Name of Pub/Sub topic. Every message published in this topic will trigger function execution.
--trigger-event=EVENT_TYPE Specifies which action should trigger the function. For a list of acceptable values, call functions event-types list.
--trigger-resource=RESOURCE Specifies which resource from --trigger-event is being observed. E.g. if --trigger-eventis providers/cloud.storage/eventTypes/object.change, --trigger-resource must be a bucket name. For a list of expected resources, call functions event-types list.
GCLOUD WIDE FLAGS Flags available to all commands: --account, --configuration, --flags-file, --flatten, --format, --help, --log-http, --project, --quiet, --trace-token, --user-output-enabled, --verbosity.

Installing Dependencies

To install a module, add it to the dependencies of package.json. Google will automatically install all dependencies at the deployment.

Alternatively you can run npm install MODULE_NAME, which will update package.json content.

Using Node.js 8 Environment

Currently Google still uses Node.js 6 as the default version. With that version, you can't use some new features such as async/await. But Google makes it possible for use to use Node.js 8. First, add a function that won't run on Node.js 6, as examplified below.

index.js

  const request = require('request-promise');

  exports.helloAsync = async (req, res) => {
    const result = await request('https://www.example.com');

    return res.send(result);
  };

To use Node.js 8 runtime environment, add --runtime nodejs8 parameter to the command.

gcloud functions deploy helloAsync --trigger-http --project PROJECT_NAME --runtime nodejs8