Cloud Run functions supports several methods of running your functions outside of the target deployment environment. This is particularly useful for iterative development, and for situations where you want to test your function before deploying.
The ability to run your functions without deploying them can simplify local testing, compliance with data locality restrictions, and multicloud deployments:
Data locality restrictions: Test your function locally without accessing production data, to avoid violating your organization's data locality rules.
Multicloud deployments: Multicloud function deployments are an established pattern to mitigate downtime risk in reliability-critical environments. Deploying functions to environments other than Cloud Run functions itself reduces the risk of your application experiencing unplanned downtime.
Develop functions locally using Functions Framework
You can develop and test functions locally using Functions Framework. Developing a function locally can help you test your code without having to rebuild your function container. This can save time and make it easier to test your function.
Cloud Run uses the open-source Functions Framework libraries to wrap your deployed functions in a persistent HTTP application.
The Functions Framework can also run on any other platform that supports the language itself, including your local machine, on-premises servers, and Compute Engine.
Install dependencies
In your function's directory, install the Functions Framework library for your language:
Node.js
npm install --save-dev @google-cloud/functions-framework
Python
pip3 install functions-framework
Go
go install github.com/GoogleCloudPlatform/functions-framework-go/funcframework
Java
Maven
If you're using Maven, add the
following to your pom.xml
file:
Gradle
If you're using Gradle, add the following to your
build.gradle
file:
See the Java Functions Framework library for more information.
C#
The following commands use .NET Templates to create a new .NET function codebase with the .NET Functions Framework library as a dependency:
# HTTP functions dotnet new gcf-http # CloudEvent functions dotnet new gcf-event
Ruby
In Ruby the Functions Framework must be added to your function's dependencies in order to deploy it to Cloud Run:
bundle add functions_framework
PHP
composer require google/cloud-functions-framework
Configure the Functions Framework
Before running a function using the Functions Framework, you'll first need to specify both the type and the name of the function you want to run. These attributes can be specified as either command-line interface (CLI) flag or as environment variables.
Supported function types
The Functions Framework supports both types of functions
supported by Cloud Run functions. All language runtimes
support both the http
and cloudevent
signature types.
Function type | Signature type | Description | Supporting Runtimes |
---|---|---|---|
HTTP-triggered functions |
http
|
Functions that receive and respond to HTTP requests. | All runtimes |
CloudEvent functions |
cloudevent
|
Industry-standard event format. | All runtimes |
Specify which function to run
Before running a function with the Functions Framework, you must first specify which function within your code to run. For most languages, you can do this by specifying the target function's method name as shown in the following tables. Note that there are exceptions to this rule for the Java and .NET runtimes.
Per-language instructions
See the following table for a list of configuration options supported by each language.
Node.js
CLI Argument | Environment Variable | Description |
---|---|---|
--port
|
PORT
|
The port to listen for requests on. (Default: 8080 )
|
--target
|
FUNCTION_TARGET
|
The name of the export ed function to be invoked. (Default:
function )
|
--signature-type
|
FUNCTION_SIGNATURE_TYPE
|
The signature type used by your function. Can be http
(the default) or cloudevent .
|
Python
CLI Argument | Environment Variable | Description |
---|---|---|
--port
|
PORT
|
The port to listen for requests on. (Default: 8080 )
|
--target
|
FUNCTION_TARGET
|
The name of the export ed function to be invoked. (Default:
function )
|
--signature-type
|
FUNCTION_SIGNATURE_TYPE
|
The signature type used by your function. Can be http
(the default) or cloudevent .
|
Go
Environment Variable | Description |
---|---|
PORT
|
The port to listen for requests on. (Default: 8080 )
|
Java
Argument Name | Environment Variable | Description |
---|---|---|
run.port
|
PORT
|
The port to listen for requests on. (Default: 8080 )
|
run.functionTarget
|
FUNCTION_TARGET
|
The name of the export ed function to be invoked. (Default:
function )
|
C#
CLI Argument | Environment Variable | Description |
---|---|---|
--port
|
PORT
|
The port to listen for requests on. (Default: 8080 )
|
--target (or only argument)
|
FUNCTION_TARGET
|
The classname of the function to be invoked. (Default:
function )
|
Ruby
CLI Argument | Environment Variable | Description |
---|---|---|
--port
|
PORT
|
The port to listen for requests on. (Default: 8080 )
|
--target
|
FUNCTION_TARGET
|
The name of the export ed function to be invoked. (Default:
function )
|
PHP
Environment Variable | Description |
---|---|
FUNCTION_TARGET
|
The name of the function to be invoked. (Default:
function )
|
FUNCTION_SIGNATURE_TYPE
|
The signature type used by your function. Can be http
(the default) or cloudevent .
|
Follow these instructions to configure and run the Functions Framework:
Node.js
The Node.js Functions Framework lets you specify your function's name and signature type as command line arguments or environment variables.
You can also specify these values in the package.json
buildfile by adding a
start
script with the required CLI arguments as shown in the example below.
"scripts": { "start": "npx functions-framework --target=YOUR_FUNCTION_NAME [--signature-type=YOUR_SIGNATURE_TYPE]" }
The same can be done using environment variables:
"scripts": { "start": "FUNCTION_TARGET=YOUR_FUNCTION_NAME FUNCTION_SIGNATURE_TYPE=YOUR_SIGNATURE_TYPE npx functions-framework" }
Replace YOUR_FUNCTION_NAME with the method name of your function, and YOUR_SIGNATURE_TYPE (if applicable) with the signature type of your function as shown in supported function types.
Python
The Python Functions Framework lets you specify your function's name and signature type as command line arguments or environment variables. Command-line arguments must be specified when you run the framework.
Go
The Go Functions Framework uses funcframework.RegisterHTTPFunctionContext
to
specify the function target and signature type.
Java
The Java Functions Framework accepts configuration data from three different sources, in the following priority order (most specific to least specific):
- Command-line arguments
- Buildfiles
- Environment variables
Command-line arguments
Maven
You can specify the function you want to run by adding the following
command-line interface (CLI) flag to your mvn
commands:
-Drun.functionTarget=YOUR_FUNCTION_NAME
You can also specify the target port by adding the following CLI flag in a similar manner:
-Drun.port=12345
Gradle
Gradle's CLI flags are nearly identical to Maven's. The only change Gradle makes
is to swap the leading -D
in each flag for a -P
as shown in the following
example:
# Maven version -Drun.functionTarget=... # Gradle version -Prun.functionTarget=...
Buildfiles
You can also specify the function you want to run in your project's buildfile. While Maven and Gradle have similar CLI flags, their buildfile clauses differ significantly.
Maven
Maven buildfiles are named pom.xml
. Add the following clause to this file to
specify a target function:
Replace <functionTarget>
with the class name of your
function. For example, a function in package functions
with class name
HelloCloudFunctions
would have a class name of
functions.HelloCloudFunctions
. This is relative to the parent build file
- either pom.xml
or build.gradle
.
Gradle
Gradle buildfiles are named build.gradle
. Add the following clause to
this file to specify a target function:
C#
If you create your project using dotnet new
and one of the templates specified
earlier, the .NET Functions Framework will automatically detect your function.
If your project contains multiple functions, see the Running the Framework section for information on how to run a specific function.
Ruby
The Ruby Functions Framework lets you specify your function's name and signature type as command line arguments or environment variables. Command-line arguments must be specified when you run the framework.
PHP
The PHP Functions Framework allows you to specify environment variables as command line arguments.
You can also specify these values in the composer.json
buildfile by adding a
start
script as shown in the example below.
"scripts": { "start": [ "Composer\\Config::disableProcessTimeout", "FUNCTION_TARGET=YOUR_FUNCTION_NAME php -S localhost:${PORT:-8080} vendor/bin/router.php" ]. }
Replace YOUR_FUNCTION_NAME with the name of your function, and YOUR_SIGNATURE_TYPE (if applicable; it is not included in the example shown here).
Run your function
Use the following command to run your function with the Functions Framework.
By default, your function will be accessible at localhost:8080
unless you
explicitly specify a PORT
value.
Node.js
npm start
Python
Using command line arguments:
functions-framework --target=YOUR_FUNCTION_NAME
Using environment variables:
FUNCTION_TARGET=YOUR_FUNCTION_NAME functions-framework
Replace YOUR_FUNCTION_NAME with your function's method name.
Go
First create a cmd/main.go
file as described on the
Functions Framework for Go
site.
cd cmd go build ./cmd
Using environment variables:
cd cmd go build PORT=8080 ./cmd
Java
Maven
Use the following command to run a function specified in pom.xml
:
mvn function:run
Use the following command to run a function specified in a command-line argument:
mvn function:run -Drun.functionTarget=YOUR_FUNCTION_NAME
Use the following command to run a function specified as an environment variable:
FUNCTION_TARGET=YOUR_FUNCTION_NAME mvn function:run
Replace YOUR_FUNCTION_NAME with your function's classname.
Gradle
Use the following command to run a function specified in build.gradle
:
./gradlew runFunction
Use the following command to run a function specified in a command-line argument:
./gradlew runFunction -Prun.functionTarget=YOUR_FUNCTION_NAME
Use the following command to run a function specified as an environment variable:
FUNCTION_TARGET=YOUR_FUNCTION_NAME ./gradlew runFunction
Replace YOUR_FUNCTION_NAME with your function's classname.
C#
Use the following command to run your function when exactly one function is present in the current .NET project. Note that this is the default structure for template-created projects.
dotnet run
If your .NET project contains multiple functions, use the following command to run a specific function. Replace YOUR_FUNCTION_CLASSNAME with your function's classname, including the namespace.
dotnet run YOUR_FUNCTION_CLASSNAME
If you want to run multiple functions simultaneously, you'll need to run
multiple Functions Framework instances. To avoid conflicts between running
framework instances, each instance should use a different PORT
value. The
following command shows how to run a function with a PORT
value of 8080
.
Using command line arguments:
dotnet run --target YOUR_FUNCTION_CLASSNAME --port 8080
Using environment variables:
FUNCTION_TARGET=YOUR_FUNCTION_CLASSNAME PORT=8080 dotnet run
Ruby
Using command line arguments:
bundle exec functions-framework-ruby --target YOUR_FUNCTION_NAME
Using environment variables:
FUNCTION_TARGET=YOUR_FUNCTION_NAME bundle exec functions-framework-ruby
Replace YOUR_FUNCTION_NAME with your function's method name.
PHP
export FUNCTION_TARGET=YOUR_FUNCTION_NAME php -S localhost:8080 vendor/bin/router.php
Replace YOUR_FUNCTION_NAME with your function's name.
Call your locally running function
The exercises in this section assume that you've
set up a locally running function on
localhost
using Functions Framework.
You can trigger locally-running functions by sending them HTTP requests routed using a local serving process.
HTTP functions
When you test your HTTP function from your development environment, it normally
listens for requests on localhost:8080
. This interface is only accessible from
the machine or VM your function is running on; requests sent from any other
system can't reach it. For this reason, you must issue the HTTP request from the
same system that your function is running on. In the following examples, if your
function is listening on a port other than 8080, replace the 8080 in the
example with the port number for your function.
Testing HTTP functions with Cloud Shell
If you're using Cloud Shell to build and test your function, start your
function locally in the Cloud Shell terminal window, then issue the HTTP
trigger request from a browser or curl
instance as follows:
Browser
Click the icon on your Cloud Shell toolbar and choose port 8080 or Change port to pick a different port. This opens a browser window on the correct system and issues a GET request to the indicated port.
Curl
To control the format of your HTTP request or to see the unformatted reply,
use curl
:
- Click the + icon on the Cloud Shell menu bar to open a new terminal window on the same system your function is running on.
From within that window, run the
curl
command to trigger your function. For example:curl localhost:8080
Testing HTTP functions on your desktop server
If you're building and running your function on your local desktop system, first
start your function locally, then issue your HTTP trigger request from a browser
or curl
instance as follows:
Browser
Open a new browser window or tab and type http://localhost:8080
into the
browser address bar. This opens a browser window to localhost:8080
on your
desktop server to trigger your function.
Curl
Open a new terminal window on your local desktop, then run the curl
command
in that window to trigger your function. For example:
curl localhost:8080
This runs the specified curl
command to trigger your function and displays
the unformatted response.
CloudEvent functions
You can send sample events to
CloudEvent functions
using curl
. The following curl
requests show how to send sample
Pub/Sub and
Cloud Storage events to a
CloudEvent function running at localhost:8080
.
Pub/Sub
curl localhost:8080 \ -X POST \ -H "Content-Type: application/json" \ -H "ce-id: 123451234512345" \ -H "ce-specversion: 1.0" \ -H "ce-time: 2020-01-02T12:34:56.789Z" \ -H "ce-type: google.cloud.pubsub.topic.v1.messagePublished" \ -H "ce-source: //pubsub.googleapis.com/projects/MY-PROJECT/topics/MY-TOPIC" \ -d '{ "message": { "data": "d29ybGQ=", "attributes": { "attr1":"attr1-value" } }, "subscription": "projects/MY-PROJECT/subscriptions/MY-SUB" }'
Cloud Storage
curl localhost:8080 \ -X POST \ -H "Content-Type: application/json" \ -H "ce-id: 123451234512345" \ -H "ce-specversion: 1.0" \ -H "ce-time: 2020-01-02T12:34:56.789Z" \ -H "ce-type: google.cloud.storage.object.v1.finalized" \ -H "ce-source: //storage.googleapis.com/projects/_/buckets/MY-BUCKET-NAME" \ -H "ce-subject: objects/MY_FILE.txt" \ -d '{ "bucket": "MY_BUCKET", "contentType": "text/plain", "kind": "storage#object", "md5Hash": "...", "metageneration": "1", "name": "MY_FILE.txt", "size": "352", "storageClass": "MULTI_REGIONAL", "timeCreated": "2020-04-23T07:38:57.230Z", "timeStorageClassUpdated": "2020-04-23T07:38:57.230Z", "updated": "2020-04-23T07:38:57.230Z" }'