Write Cloud Run functions Stay organized with collections Save and categorize content based on your preferences.
This page describes how to write HTTP and event-drivenCloud Run functions with the Functions Framework.
Functions Framework overview
When writing functions source code, you must use theFunctionsFramework, an opensource library for writing Cloud Run functions. With theFunctions Framework, you can write lightweight functions that run inCloud Run and in other environments, including your local developmentmachine and Knative-based environments.
The Functions Framework lets you:
- Invoke a Cloud Run function in response to a request.
- Automatically unmarshal events conforming to theCloudEvents specification, an industry-standardspecification for describing event data in a common way.
- Start a local development server for testing.
The Functions Framework provides an interface for building modular services. Touse the Functions Framework in your source code, specify the following:
Function entry point
Your source code must define a function entry point, which is the code that runswhen Cloud Run invokes your function. You specify this entry point whenyou deploy your function.
How you define the entry point depends on the language runtime you use. Somelanguages 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, youmust specify one of the two signature types:
- HTTP functions: Registers an HTTP handlerfunction. Use an HTTP function when your function needs a URL endpoint andmust respond to HTTP requests, such as for webhooks.
- Event-driven functions, also known asCloudEvents functions: Registers a CloudEvents handler function. Use anevent-driven function when your function is triggered directly in responseto events within your Google Cloud project, such as messages on aPub/Sub topic or changes in a Cloud Storage bucket.
Source directory structure
The Functions Framework is supported in a number of programming languages. Thelanguage runtime you choose and the type of function you want to writedetermines how to structure your code and implement your function.
For Cloud Run to locate your function definition, eachlanguage 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 filenamedindex.js at the root of your function directory. To specify a differentmain source file, use themain field in yourpackage.json file.
Yourpackage.json file must also include theFunctions Framework for Node.jsas a dependency:
{"main":"index.js","dependencies":{"@google-cloud/functions-framework":"^3.0.0"},"type":"module"}npm install @google-cloud/functions-framework.The code in your main file must define yourfunction entry pointand can import other code and Node.js modules. The main file can alsodefine multiple function entry points that can be deployed separately.
See theNode.js runtime overview and theFunctions Framework for Node.jsfor 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 namedmain.py at theroot of your function directory. You must name your main filemain.py.
Yourrequirements.txt file must include theFunctions Framework for Pythonas a dependency:
functions-framework==3.*The code in yourmain.py file must define yourfunction entry point and can import other code and externaldependencies as normal. Themain.py file can also define multiple functionentry points that can be deployed separately.
See thePython runtime overview and theFunctions Framework for Pythonfor 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 packageand its source files can have any name, except your function cannot be inpackage main. If you need amain package, for example for local testing,you can create one in a subdirectory:
.├── myfunction.go├── go.mod└── cmd/ └── main.go
Yourgo.mod file must include theFunctions Framework for Goas a dependency:
moduleexample.com/my-modulerequire(github.com/GoogleCloudPlatform/functions-framework-gov1.5.2)go get github.com/GoogleCloudPlatform/functions-framework-go.The code in your root package must define yourfunction entry point and can import other code from subpackagesand dependencies as normal. Your package can also define multiple functionentry points that can be deployed separately.
Note: For an example of setting up a basic Cloud Run project in Go,see theFunctions Framework for Go Quickstart on GitHub.See theGo runtime overview and theFunctions Framework for Gofor 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 thesrc/main/java/ directory and can haveany name. If your source files declare a package, add an extra directory undersrc/main/java with the name of the package:
.├── pom.xml└── src/ └── main/ └── java/ └── mypackage/ └── MyFunction.java
We recommend putting associated tests under asrc/test/java/ subdirectory.
java directories to language-appropriate names (such asgroovy,kotlin, orscala).Yourpom.xml file must include theFunctions Framework for Javaas 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 yourfunction entry point and can import other code and externaldependencies as normal. Your source files can also define multiple functionentry points that can be deployed separately.
See theJava runtime overview and theFunctions Framework for Javafor 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.
Note: The same pattern applies if you use F# or Visual Basic, but withappropriate file extensions (.fs and.fsproj for F#,.vb and.vbprojfor Visual Basic).Your project file must include theFunctions Framework for .NETas a dependency:
...<PackageReferenceInclude="Google.Cloud.Functions.Hosting"Version="1.0.0"/>...The code in your source files must define yourfunction entry point and can import other code and externaldependencies as normal. Your source files can also define multiple functionentry points that can be deployed separately.
Note: For information about file structure in relation to functions that usemultiple local .NET projects, seeDeploying a function with a local project dependency.See the.NET runtime overview and theFunctions Framework for .NETfor 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 namedapp.rb at theroot of your function directory. Your main file must be namedapp.rb.
YourGemfile file must include theFunctions Framework for Rubyas a dependency:
source "https://rubygems.org"gem "functions_framework", "~> 1.0"bundle add functions_framework.The code in yourapp.rb file must define yourfunction entry point and can import other code and externaldependencies as normal. Theapp.rb file can also define multiple functionentry points that can be deployed separately.
See theRuby runtime overview and theFunctions Framework for Rubyfor 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 namedindex.php at theroot of your function directory. You must name your main fileindex.php.
Yourcomposer.json file must include theFunctions Framework for PHPas a dependency:
{"require":{"google/cloud-functions-framework":"^1.1"}}composer require google/cloud-functions-framework.The code in yourindex.php file must define yourfunction entry point and can import other code andexternal dependencies as normal. Theindex.php file can also define multiplefunction entry points that can be deployed separately.
See thePHP runtime overview and theFunctions Framework for PHPfor more details.
If you group multiple functions into a single project, be aware that everyfunction might end up sharing the same set of dependencies. However, some of thefunctions might not need all of the dependencies.
Where possible, we recommend splitting up large multi-function codebases andputting each function in its own top-level directory as shown in the precedingexamples, with its own source and project configuration files. This approachminimizes the number of dependencies required for a particular function, whichin turn reduces the amount of memory your function needs.
Write HTTP functions
Write an HTTP function when you want to invoke a function through an HTTP(S)request. To allow for HTTP semantics, you use the Function Framework and specifythe HTTP Function signature to accept HTTP-specific arguments.
The following example shows a basic HTTP function source file for each runtime.For a complete working example, seeDeploy a Cloud Run functionusing theGoogle Cloud CLI. Formore information about where to locate your source code, seeSource directorystructure.
Node.js
ES module
import{http}from'@google-cloud/functions-framework';http('myHttpFunction',(req,res)=>{// Your code here// Send an HTTP responseres.send('OK');});Add the following dependencies, including"type": "module" in yourpackage.json file:
{"dependencies":{"@google-cloud/functions-framework":"^3.0.0"},"type":"module"}CommonJS module
constfunctions=require('@google-cloud/functions-framework');// Register an HTTP function with the Functions Frameworkfunctions.http('myHttpFunction',(req,res)=>{// Your code here// Send an HTTP responseres.send('OK');});Add the following dependencies in yourpackage.json file:
{"dependencies":{"@google-cloud/functions-framework":"^3.0.0"}}In Node.js, you register an HTTP handler function with theFunctions Framework for Node.js.Your HTTP handler function must be anExpress middleware functionthat accepts therequestandresponse arguments and sendsan HTTP response.
Cloud Run automatically parses the request body for you based on therequest'sContent-Type header usingbody-parser,so you can access thereq.body andreq.rawBody objects in your HTTP handler.
Thefunction entry pointis the name with which the handler is registered with the Functions Framework.In this example, the entry point ismyHttpFunction.
Python
importfunctions_framework# Register an HTTP function with the Functions Framework@functions_framework.httpdefmy_http_function(request):# Your code here# Return an HTTP responsereturn'OK'In Python, you register an HTTP handler function with theFunctions Framework for Python.Your HTTP handler function must accept aFlask requestobject as an argument and returna value that Flask can convert into an HTTP response object.
Thefunction entry pointis the name with which the handler is registered with the Functions Framework.In this example, the entry point ismy_http_function.
Go
packagemyhttpfunctionimport("fmt""net/http""github.com/GoogleCloudPlatform/functions-framework-go/functions")funcinit(){// Register an HTTP function with the Functions Frameworkfunctions.HTTP("MyHTTPFunction",myHTTPFunction)}// Function myHTTPFunction is an HTTP handlerfuncmyHTTPFunction(whttp.ResponseWriter,r*http.Request){// Your code here// Send an HTTP responsefmt.Fprintln(w,"OK")}In Go, you register an HTTP handler function with theFunctions Framework for Goin yourinit() function. Your HTTP handler function must use the standardhttp.HandlerFuncinterface to send an HTTP response.
Thefunction entry pointis the name with which the handler is registered with the Functions Framework.In this example, the entry point isMyHTTPFunction.
Your HTTP handler function must implement the standardhttp.HandlerFuncinterface. It accepts anhttp.ResponseWriter interface that your function usesto create a reply to the request, and a pointer to anhttp.Request struct containing thedetails of the inbound HTTP request.
Java
packagemyhttpfunction;importcom.google.cloud.functions.HttpFunction;importcom.google.cloud.functions.HttpRequest;importcom.google.cloud.functions.HttpResponse;// Define a class that implements the HttpFunction interfacepublicclassMyHttpFunctionimplementsHttpFunction{// Implement the service() method to handle HTTP requests@Overridepublicvoidservice(HttpRequestrequest,HttpResponseresponse)throwsException{// Your code here// Send an HTTP responseresponse.getWriter().write("OK");}}In Java, you use theFunctions Framework Java APIto implement an HTTP handler class with theHttpFunctioninterface. Theservice() method must send an HTTP response.
Thefunction entry pointis the fully-qualified name of the HTTP handler class, including the packagename. In this example, the entry point ismyhttpfunction.MyHttpFunction.
Yourservice method receives anHttpRequestobject describing the inbound HTTP request, and anHttpResponseobject that your function populates with a response message.
.NET
usingGoogle.Cloud.Functions.Framework;usingMicrosoft.AspNetCore.Http;usingSystem.Threading.Tasks;namespaceMyProject{// Define a class that implements the IHttpFunction interfacepublicclassMyHttpFunction:IHttpFunction{// Implement the HandleAsync() method to handle HTTP requestspublicasyncTaskHandleAsync(HttpContextcontext){// Your code here// Send an HTTP responseawaitcontext.Response.WriteAsync("OK");}}}In .NET runtimes, you use theFunctions Framework for .NETto implement an HTTP handler class with theIHttpFunctioninterface. TheHandleAsync() method accepts a standard ASP.NETHttpContextobject as an argument and must send an HTTP response.
Thefunction entry pointis the fully-qualified name of the HTTP handler class, including thenamespace. In this example, the entry point isMyProject.MyHttpFunction.
Ruby
require"functions_framework"# Register an HTTP function with the Functions FrameworkFunctionsFramework.http"my_http_function"do|request|# Your code here# Return an HTTP response"OK"endIn Ruby, you register an HTTP handler function with theFunctions Framework for Ruby.Your HTTP handler function must accept aRack requestobject as an argument and returna value that can be used as an HTTP response.
Thefunction entry pointis the name with which the handler is registered with the Functions Framework.In this example, the entry point ismy_http_function.
PHP
<?phpuse Google\CloudFunctions\FunctionsFramework;use Psr\Http\Message\ServerRequestInterface;// Register an HTTP function with the Functions FrameworkFunctionsFramework::http('myHttpFunction', 'myHttpHandler');// Define your HTTP handlerfunction myHttpHandler(ServerRequestInterface $request): string{ // Your code here // Return an HTTP response return 'OK';}In PHP, you register an HTTP handler function with theFunctions Framework for PHP.Your HTTP handler function must accept an argument that implements the PSR-7ServerRequestInterfaceinterface, and must return an HTTP response as either a string or an objectthat implements the PSR-7ResponseInterfaceinterface.
Thefunction entry pointis the name with which the handler is registered with the Functions Framework.In this example, the entry point ismyHttpFunction.
HTTP request and responses
When you register an HTTP handler function with the Functions Framework, yourHTTP handler can inspect the request method and perform different actions basedon the method.
When you configure an event provider to send HTTP requests to yourCloud Run function, your function sends an HTTP response. If thefunction creates background tasks (such as with threads, futures, JavaScriptPromise objects, callbacks, or system processes), you must terminate orotherwise resolve these tasks before sending an HTTP response. Any tasks notterminated before the HTTP response is sent might not be completed, and mightcause undefined behavior.
Handle CORS
Cross-Origin Resource Sharing (CORS)is a way to let applications running on one domain access resources from anotherdomain. For example, you might need to let your domain make requests to theCloud Run functions domain to access your function.
To allow cross-origin requests to your function, set theAccess-Control-Allow-Originheader as appropriate on your HTTP response. Forpreflighted cross-origin requests,you must respond to the preflightOPTIONS request with a204 response codeand additional headers.
Node.js
constfunctions=require('@google-cloud/functions-framework');/** * HTTP function that supports CORS requests. * * @param {Object} req Cloud Function request context. * @param {Object} res Cloud Function response context. */functions.http('corsEnabledFunction',(req,res)=>{// Set CORS headers for preflight requests// Allows GETs from any origin with the Content-Type header// and caches preflight response for 3600sres.set('Access-Control-Allow-Origin','*');if(req.method==='OPTIONS'){// Send response to OPTIONS requestsres.set('Access-Control-Allow-Methods','GET');res.set('Access-Control-Allow-Headers','Content-Type');res.set('Access-Control-Max-Age','3600');res.status(204).send('');}else{res.send('Hello World!');}});Python
importfunctions_framework@functions_framework.httpdefcors_enabled_function(request):# For more information about CORS and CORS preflight requests, see:# https://developer.mozilla.org/en-US/docs/Glossary/Preflight_request# Set CORS headers for the preflight requestifrequest.method=="OPTIONS":# Allows GET requests from any origin with the Content-Type# header and caches preflight response for an 3600sheaders={"Access-Control-Allow-Origin":"*","Access-Control-Allow-Methods":"GET","Access-Control-Allow-Headers":"Content-Type","Access-Control-Max-Age":"3600",}return("",204,headers)# Set CORS headers for the main requestheaders={"Access-Control-Allow-Origin":"*"}return("Hello World!",200,headers)Go
// Package http provides a set of HTTP Cloud Functions samples.packagehttpimport("fmt""net/http""github.com/GoogleCloudPlatform/functions-framework-go/functions")// CORSEnabledFunction is an example of setting CORS headers.// For more information about CORS and CORS preflight requests, see// https://developer.mozilla.org/en-US/docs/Glossary/Preflight_request.funcCORSEnabledFunction(whttp.ResponseWriter,r*http.Request){// Set CORS headers for the preflight requestifr.Method==http.MethodOptions{w.Header().Set("Access-Control-Allow-Origin","*")w.Header().Set("Access-Control-Allow-Methods","POST")w.Header().Set("Access-Control-Allow-Headers","Content-Type")w.Header().Set("Access-Control-Max-Age","3600")w.WriteHeader(http.StatusNoContent)return}// Set CORS headers for the main request.w.Header().Set("Access-Control-Allow-Origin","*")fmt.Fprint(w,"Hello, World!")}funcinit(){functions.HTTP("CORSEnabledFunction",CORSEnabledFunction)}Java
importcom.google.cloud.functions.HttpFunction;importcom.google.cloud.functions.HttpRequest;importcom.google.cloud.functions.HttpResponse;importjava.io.BufferedWriter;importjava.io.IOException;importjava.net.HttpURLConnection;publicclassCorsEnabledimplementsHttpFunction{// corsEnabled is an example of setting CORS headers.// For more information about CORS and CORS preflight requests, see// https://developer.mozilla.org/en-US/docs/Glossary/Preflight_request.@Overridepublicvoidservice(HttpRequestrequest,HttpResponseresponse)throwsIOException{// Set CORS headers// Allows GETs from any origin with the Content-Type// header and caches preflight response for 3600sresponse.appendHeader("Access-Control-Allow-Origin","*");if("OPTIONS".equals(request.getMethod())){response.appendHeader("Access-Control-Allow-Methods","GET");response.appendHeader("Access-Control-Allow-Headers","Content-Type");response.appendHeader("Access-Control-Max-Age","3600");response.setStatusCode(HttpURLConnection.HTTP_NO_CONTENT);return;}// Handle the main request.BufferedWriterwriter=response.getWriter();writer.write("CORS headers set successfully!");}}.NET
usingGoogle.Cloud.Functions.Framework;usingMicrosoft.AspNetCore.Http;usingSystem.Net;usingSystem.Threading.Tasks;namespaceCors;// For more information about CORS and CORS preflight requests, see// https://developer.mozilla.org/en-US/docs/Glossary/Preflight_request.publicclassFunction:IHttpFunction{publicasyncTaskHandleAsync(HttpContextcontext){HttpRequestrequest=context.Request;HttpResponseresponse=context.Response;// Set CORS headers// Allows GETs from any origin with the Content-Type// header and caches preflight response for 3600sresponse.Headers.Append("Access-Control-Allow-Origin","*");if(HttpMethods.IsOptions(request.Method)){response.Headers.Append("Access-Control-Allow-Methods","GET");response.Headers.Append("Access-Control-Allow-Headers","Content-Type");response.Headers.Append("Access-Control-Max-Age","3600");response.StatusCode=(int)HttpStatusCode.NoContent;return;}awaitresponse.WriteAsync("CORS headers set successfully!",context.RequestAborted);}}Ruby
FunctionsFramework.http"cors_enabled_function"do|request|# For more information about CORS and CORS preflight requests, see# https://developer.mozilla.org/en-US/docs/Glossary/Preflight_request# for more information.# Set CORS headers for the preflight requestifrequest.options?# Allows GET requests from any origin with the Content-Type# header and caches preflight response for an 3600sheaders={"Access-Control-Allow-Origin"=>"*","Access-Control-Allow-Methods"=>"GET","Access-Control-Allow-Headers"=>"Content-Type","Access-Control-Max-Age"=>"3600"}[204,headers,[]]else# Set CORS headers for the main requestheaders={"Access-Control-Allow-Origin"=>"*"}[200,headers,["Hello World!"]]endendPHP
use Psr\Http\Message\ResponseInterface;use Psr\Http\Message\ServerRequestInterface;use GuzzleHttp\Psr7\Response;function corsEnabledFunction(ServerRequestInterface $request): ResponseInterface{ // Set CORS headers for preflight requests // Allows GETs from any origin with the Content-Type header // and caches preflight response for 3600s $headers = ['Access-Control-Allow-Origin' => '*']; if ($request->getMethod() === 'OPTIONS') { // Send response to OPTIONS requests $headers = array_merge($headers, [ 'Access-Control-Allow-Methods' => 'GET', 'Access-Control-Allow-Headers' => 'Content-Type', 'Access-Control-Max-Age' => '3600' ]); return new Response(204, $headers, ''); } else { return new Response(200, $headers, 'Hello World!'); }}If CORS is not set up properly, you might see errors like the following:
XMLHttpRequest cannot load https://YOUR_FUNCTION_URL.No 'Access-Control-Allow-Origin' header is present on the requested resource.Origin 'https://YOUR_DOMAIN' is therefore not allowed access.
CORS limitations
For preflighted cross-origin requests, preflight OPTIONS requests are sentwithout an Authorization header, so they will be rejected on all HTTP functionsthat require authentication. Because the preflight requests fail, the mainrequests will also fail. To work around this limitation, use one of thefollowing options:
- Allow public accessof your function.
- Configure Identity-Aware Proxyfor your function, which provides the Authorization header for preflightOPTIONS requests sent to Cloud Run functions.
- Host your web app and Cloud Run on the same domain to avoid CORS.You can do this byintegrating Firebase Hosting with Cloud Run functions.
Write event-driven functions
Write an event-driven function when you want a function to be triggered directlyin response to events within your Google Cloud project, such as messages on aPub/Sub topic or changes in a Cloud Storage bucket.
Event-driven functions are based onCloudEvents, anindustry-standard specification for describing event data in a common way. Youcan learn more about the CloudEvents specification at theCloudEvents GitHubrepository. The CloudEvents project alsoprovides a set ofCloudEvents SDKsto help work with CloudEvents objects in your code.
The following example shows an event-driven function source file for eachruntime. SeeSource directorystructure for information aboutwhere to locate your source code.
Node.js
ES module
import{cloudEvent}from"@google-cloud/functions-framework";cloudEvent('myCloudEventFunction',cloudEvent=>{// Your code here// Access the CloudEvent data payload using cloudEvent.data});Add the following dependencies, including"type": "module" in yourpackage.json file:
{"dependencies":{"@google-cloud/functions-framework":"^3.0.0"},"type":"module"}CommonJS module
constfunctions=require('@google-cloud/functions-framework');// Register a CloudEvent function with the Functions Frameworkfunctions.cloudEvent('myCloudEventFunction',cloudEvent=>{// Your code here// Access the CloudEvent data payload using cloudEvent.data});Add the following dependencies in yourpackage.json file:
{"dependencies":{"@google-cloud/functions-framework":"^3.0.0"}}In Node.js, you register a CloudEvent handler function with theFunctions Framework for Node.js.Your handler function must accept aCloudEventobject as an argument.
Thefunction entry pointis the name with which the handler is registered with the Functions Framework.In this example, the entry point ismyCloudEventFunction.
Python
importfunctions_framework# Register a CloudEvent function with the Functions Framework@functions_framework.cloud_eventdefmy_cloudevent_function(cloud_event):# Your code here# Access the CloudEvent data payload via cloud_event.dataIn Python, you register a CloudEvent handler function with theFunctions Framework for Python.Your handler function must accept aCloudEventobject as an argument.
Thefunction entry pointis the name of the handler function registered with the Functions Framework.In this example, the entry point ismy_cloudevent_function.
Go
packagemycloudeventfunctionimport("context""github.com/GoogleCloudPlatform/functions-framework-go/functions""github.com/cloudevents/sdk-go/v2/event")funcinit(){// Register a CloudEvent function with the Functions Frameworkfunctions.CloudEvent("MyCloudEventFunction",myCloudEventFunction)}// Function myCloudEventFunction accepts and handles a CloudEvent objectfuncmyCloudEventFunction(ctxcontext.Context,eevent.Event)error{// Your code here// Access the CloudEvent data payload using e.Data() or e.DataAs(...)// Returning an error causes its message to be logged.// Example:err:=myInternalFunction()// may return an erroriferr!=nil{// Append error message to logreturnerr}// Return nil if no error occurredreturnnil}In Go, you register a CloudEvent handler function with theFunctions Framework for Go.Your handler function must accept a CloudEventsevent.Eventobject as an argument.
Thefunction entry pointis the name with which the handler is registered with the Functions Framework.In this example, the entry point isMyCloudEventFunction.
Java
packagemycloudeventfunction;importcom.google.cloud.functions.CloudEventsFunction;importio.cloudevents.CloudEvent;// Define a class that implements the CloudEventsFunction interfacepublicclassMyCloudEventFunctionimplementsCloudEventsFunction{// Implement the accept() method to handle CloudEvents@Overridepublicvoidaccept(CloudEventevent){// Your code here// Access the CloudEvent data payload using event.getData()// To get the data payload as a JSON string, use:// new String(event.getData().toBytes())}}In Java, you use theFunctions Framework Java APIto implement a CloudEvent handler class with theCloudEventsFunctioninterface. Theaccept() method must accept aCloudEventobject as an argument and perform any processing on the event.
Thefunction entry pointis the fully-qualified name of the CloudEvent handler class, including thepackage name. In this example, the entry point ismycloudeventfunction.MyCloudEventFunction.
.NET
usingCloudNative.CloudEvents;usingGoogle.Cloud.Functions.Framework;usingSystem.Threading;usingSystem.Threading.Tasks;namespaceMyProject{// Define a class that implements the ICloudEventFunction<T> interfacepublicclassMyCloudEventFunction:ICloudEventFunction<CloudEventDataType>{// Implement the HandleAsync() method to handle CloudEventspublicTaskHandleAsync(CloudEventcloudEvent,CloudEventDataTypedata,CancellationTokencancellationToken){// Your code here// The data argument represents the CloudEvent data payload// Signal function completionreturnTask.CompletedTask;}}}
In .NET runtimes, you use theFunctions Framework for .NETto implement a CloudEvent handler class with theICloudEventFunction<T>interface. TheHandleAsync() method accepts aCloudEventobject and the associated CloudEvent data payload as arguments.
The type of the CloudEvent data payload argument, shown in the example code asCloudEventDataType, must correspond to the type of eventthe function handles. TheGoogle CloudEvents .NET libraryprovides data types for the various events supported by Google.
Thefunction entry pointis the fully-qualified name of the CloudEvent handler class, including thenamespace. In this example, the entry point isMyProject.MyCloudEventFunction.
Ruby
require"functions_framework"# Register a CloudEvent function with the Functions FrameworkFunctionsFramework.cloud_event"my_cloudevent_function"do|cloud_event|# Your code here# Access the CloudEvent data payload via cloud_event.dataendIn Ruby, you register a CloudEvent handler function with theFunctions Framework for Ruby.Your handler function must accept a CloudEventsEventobject as an argument.
Thefunction entry pointis the name with which the handler is registered with the Functions Framework.In this example, the entry point ismy_cloudevent_function.
PHP
<?phpuse CloudEvents\V1\CloudEventInterface;use Google\CloudFunctions\FunctionsFramework;// Register a CloudEvent function with the Functions FrameworkFunctionsFramework::cloudEvent('myCloudEventFunction', 'myCloudEventHandler');// Define your CloudEvent handlerfunction myCloudEventHandler(CloudEventInterface $event): void{ // Your code here // Access the CloudEvent data payload using $event->getData()}In PHP, you register a CloudEvent handler function with theFunctions Framework for PHP.Your handler function must accept an argument that conforms to theCloudEventInterfaceinterface.
Thefunction entry pointis the name with which the handler is registered with the Functions Framework.In this example, the entry point ismyCloudEventFunction.
For event-driven functions, event data is passed to your function in theCloudEvents format, with a CloudEvent data payloadcorresponding to the event type that triggers your function. SeeFunction triggers forinformation about supported triggers, event types, and associated event dataformats.
TheGoogle Eventsrepository contains resources for working with CloudEvents issued by Google.
Function termination
Cloud Run considers event-driven function execution complete when thefunction returns. If the function creates background tasks (such as withthreads, futures, JavaScript Promise objects, callbacks, or system processes),you must terminate or otherwise resolve these tasks before returning from yourfunction. Any tasks not terminated before the function returns might not becompleted, and might cause undefined behavior.
Automatic retries
Event-driven functions can be configured to automatically retry failedinvocations. SeeRetrying event-driven functionsfor more information.
What's next
Except as otherwise noted, the content of this page is licensed under theCreative Commons Attribution 4.0 License, and code samples are licensed under theApache 2.0 License. For details, see theGoogle Developers Site Policies. Java is a registered trademark of Oracle and/or its affiliates.
Last updated 2025-12-15 UTC.