Write Cloud Run functions

This page provides an introduction for writing Cloud Run functions with the Functions Framework.

When writing functions source code, you must use the Functions Framework, an open source library for writing Cloud Run functions. With the Functions Framework, you can write lightweight functions that run in Cloud Run and in other environments, including your local development machine and Knative-based environments.

The Functions Framework lets you:

  • Invoke a Cloud Run function in response to a request.
  • Automatically unmarshal events conforming to the CloudEvents spec, an industry-standard specification for describing event data in a common way.
  • Start a local development server for quick testing.

Write functions with the Functions Framework

The Functions Framework provides an interface for building modular services. To use the Functions Framework in your source code, specify the following:

Function entry point

Your source code must define an entry point for your function, which is the particular code executed when the Cloud Run function is invoked. You specify this entry point when you deploy your function.

How you define the entry point depends on the language runtime you use. Some languages use a function as their entry point, while others use a class.

Signature Type

When you write the source code of a function with the Functions Framework, you must specify one of the two signature types:

  • HTTP functions: A function that registers an HTTP handler function. See Write HTTP functions for more information.
  • Event-driven functions (also called CloudEvents functions): A function that registers a CloudEvents handler function. See Write event-driven functions for more information.

Use an HTTP function when you need your function to have a URL endpoint and respond to HTTP requests, such as for webhooks. Use an event-driven function when your function should be triggered directly in response to events within your Google Cloud project, such as messages on a Pub/Sub topic or changes in a Cloud Storage bucket.

Source directory structure

The Functions Framework is supported in a number of programming languages. The language runtime you choose and the type of function you want to write determines how to structure your code and implement your function.

For Cloud Run to locate your function definition, each language runtime has requirements for structuring your source code.

Node.js

The basic directory structure for Node.js functions is as follows:

.
├── index.js
└── package.json

By default, Cloud Run attempts to load source code from a file named index.js at the root of your function directory. To specify a different main source file, use the main field in your package.json file.

Your package.json file must also include the Functions Framework for Node.js as a dependency:

{
  "main": "index.js",
  "dependencies": {
    "@google-cloud/functions-framework": "^3.0.0"
  }
}

The code in your main file must define your function entry point and can import other code and Node.js modules. The main file can also define multiple function entry points that can be deployed separately.

See the Node.js runtime overview and the Functions Framework for Node.js for more details.

Python

The basic directory structure for Python functions is as follows:

.
├── main.py
└── requirements.txt

Cloud Run loads source code from a file named main.py at the root of your function directory. You must name your main file main.py.

Your requirements.txt file must include the Functions Framework for Python as a dependency:

functions-framework==3.*

The code in your main.py file must define your function entry point and can import other code and external dependencies as normal. The main.py file can also define multiple function entry points that can be deployed separately.

See the Python runtime overview and the Functions Framework for Python for more details.

Go

The basic directory structure for Go functions is as follows:

.
├── myfunction.go
└── go.mod

Your function must be in a Go package at the root of your project. The package and its source files can have any name, except your function cannot be in package main. If you need a main package, for example for local testing, you can create one in a subdirectory:

.
├── myfunction.go
├── go.mod
└── cmd/
  └── main.go

Your go.mod file must include the Functions Framework for Go as a dependency:

module example.com/my-module

require (
  github.com/GoogleCloudPlatform/functions-framework-go v1.5.2
)

The code in your root package must define your function entry point and can import other code from subpackages and dependencies as normal. Your package can also define multiple function entry points that can be deployed separately.

See the Go runtime overview and the Functions Framework for Go for more details.

Java

The basic directory structure for Java functions is as follows:

.
├── pom.xml
└── src/
  └── main/
      └── java/
          └── MyFunction.java

Your Java source files must be under the src/main/java/ directory and can have any name. If your source files declare a package, add an extra directory under src/main/java with the name of the package:

.
├── pom.xml
└── src/
  └── main/
      └── java/
          └── mypackage/
              └── MyFunction.java

We recommend putting associated tests under a src/test/java/ subdirectory.

Your pom.xml file must include the Functions Framework for Java as a dependency:

...
    <dependency>
      <groupId>com.google.cloud.functions</groupId>
      <artifactId>functions-framework-api</artifactId>
      <version>1.0.4</version>
    </dependency>
...

The code in your source files must define your function entry point and can import other code and external dependencies as normal. Your source files can also define multiple function entry points that can be deployed separately.

See the Java runtime overview and the Functions Framework for Java for more details.

.NET

The basic directory structure for .NET functions is as follows:

.
├── MyFunction.cs
└── MyProject.csproj

You can structure your projects as you would any other .NET source code. Your source files can have any name.

Your project file must include the Functions Framework for .NET as a dependency:

...
    <PackageReference Include="Google.Cloud.Functions.Hosting" Version="1.0.0" />
...

The code in your source files must define your function entry point and can import other code and external dependencies as normal. Your source files can also define multiple function entry points that can be deployed separately.

See the .NET runtime overview and the Functions Framework for .NET for more details.

Ruby

The basic directory structure for Ruby functions is as follows:

.
├── app.rb
├── Gemfile
└── Gemfile.lock

Cloud Run loads source code from a file named app.rb at the root of your function directory. Your main file must be named app.rb.

Your Gemfile file must include the Functions Framework for Ruby as a dependency:

source "https://rubygems.org"
gem "functions_framework", "~> 1.0"

The code in your app.rb file must define your function entry point and can import other code and external dependencies as normal. The app.rb file can also define multiple function entry points that can be deployed separately.

See the Ruby runtime overview and the Functions Framework for Ruby for more details.

PHP

The basic directory structure for PHP functions is as follows:

.
├── index.php
└── composer.json

Cloud Run loads source code from a file named index.php at the root of your function directory. You must name your main file index.php.

Your composer.json file must include the Functions Framework for PHP as a dependency:

{
  "require": {
    "google/cloud-functions-framework": "^1.1"
  }
}

The code in your index.php file must define your function entry point and can import other code and external dependencies as normal. The index.php file can also define multiple function entry points that can be deployed separately.

See the PHP runtime overview and the Functions Framework for PHP for more details.

If you group multiple functions into a single project, be aware that every function might end up sharing the same set of dependencies. However, some of the functions might not need all of the dependencies.

Where possible, we recommend splitting up large multi-function codebases and putting each function in its own top-level directory as shown in the preceding examples, with its own source and project configuration files. This approach minimizes the number of dependencies required for a particular function, which in turn reduces the amount of memory your function needs.

Use Gemini Code Assist for code completions

If you have set up Gemini Code Assist, you can use the code completion feature when writing functions. As you type, Gemini makes code suggestions relevant to your current context.

Required roles

To get the permission that you need to complete code with Gemini Code Assist in Cloud Run functions, ask your administrator to grant you the Cloud AI Companion User (roles/cloudaicompanion.user) IAM role on your project. For more information about granting roles, see Manage access to projects, folders, and organizations.

This predefined role contains the cloudaicompanion.instances.completeCode permission, which is required to complete code with Gemini Code Assist in Cloud Run functions.

You might also be able to get this permission with custom roles or other predefined roles.

Try Gemini Code Assist code completions

To try Gemini Code Assist code completions, follow these steps:

  1. Set up your Cloud Run development environment in your Google Cloud project.
  2. Ensure you have the appropriate permissions to deploy functions.
  3. Ensure that Gemini Code Assist is set up for your Google Cloud user account and project.
  4. In the Google Cloud console, go to the Cloud Run page:

    Go to Cloud Run

  5. Begin configuring the Cloud Run function. If you are creating a new function, click Write a function. If you are configuring an existing function, click Services, select Filter services > Deployment type > Function, and click the function.

  6. Open the Source tab to edit your code with the text editor.

    Go to the source tab

  7. In the toolbar, click pen_spark Gemini, then select Code completion if it isn't already selected.

    Enable Code completion in the menu

  8. To try code completions, type code in the editor.

    For example, if you want to add an HTTP function using the Function Framework for Node.js, start typing functions.https. In response, Gemini generates Node.js code that's similar to the following:

    functions.https('helloHttps', (req, res) => {
      res.send(`Hello ${req.query.name || req.body.name || 'World'}!`);
    
  9. Review the generated code and take any of the following actions:

    • To accept a suggestion by Gemini, press Tab.
    • To accept the next word, press Control+Right Arrow (Command+Right Arrow on macOS).
    • To dismiss a suggestion, press Esc or continue typing.

For more details about Gemini, see the following resources:

What's next