編寫 Cloud Run 函式

本頁說明如何使用 Functions Framework 編寫 HTTP 和事件驅動的 Cloud Run 函式。

Functions Framework 總覽

編寫函式原始碼時,您必須使用 Functions Framework,這是用於編寫 Cloud Run 函式的開放原始碼程式庫。透過 Functions Framework,您可以編寫簡易函式,並在 Cloud Run 和其他環境中執行,包括本機開發電腦和以 Knative 為基礎的環境。

Functions Framework 可讓您:

  • 呼叫 Cloud Run 函式以回應要求。
  • 自動將符合 CloudEvents 規格的事件解除封送。CloudEvents 是業界標準規格,用於以通用方式描述事件資料。
  • 啟動本機開發伺服器以進行測試。

Functions Framework 提供介面,可建構模組化服務。如要在原始碼中使用 Functions Framework,請指定下列項目:

函式進入點

原始碼必須定義函式進入點,也就是 Cloud Run 叫用函式時執行的程式碼。部署函式時,您會指定這個進入點。

定義進入點的方式取決於您使用的語言執行階段。有些語言會使用函式做為進入點,有些則會使用類別。

簽名類型

使用 Functions Framework 編寫函式的原始碼時,您必須指定下列其中一種簽章類型:

  • HTTP 函式:註冊 HTTP 處理常式函式。如果函式需要網址端點,且必須回應 HTTP 要求 (例如 Webhook),請使用 HTTP 函式。
  • 事件導向函式,又稱 CloudEvents 函式:註冊 CloudEvents 處理常式函式。如果函式是直接因應 Google Cloud 專案中的事件而觸發,例如 Pub/Sub 主題上的訊息或 Cloud Storage 值區中的變更,請使用事件驅動函式。

來源目錄結構

Functions Framework 支援多種程式設計語言,您選擇的語言執行階段和想編寫的函式類型,會決定程式碼的結構和函式的實作方式。

為使 Cloud Run 能夠找到函式定義,每個語言執行階段都對原始碼結構有一定的要求。

Node.js

Node.js 函式的基本目錄結構如下:

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

根據預設,Cloud Run 會嘗試從函式目錄根層級名為 index.js 的檔案載入原始碼。如要指定其他主要來源檔案,請使用 package.json 檔案中的 main 欄位。

package.json 檔案也必須將 Node.js 適用的 Functions Framework 做為依附元件:

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

主要檔案中的程式碼必須定義函式進入點,並可匯入其他程式碼和 Node.js 模組。主要檔案也可以定義多個函式進入點,並分別部署。

詳情請參閱 Node.js 執行階段總覽Node.js 適用的 Functions Framework

Python

Python 函式的基本目錄結構如下:

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

Cloud Run 會從函式目錄根層級名為 main.py 的檔案載入原始碼。主要檔案必須命名為 main.py

requirements.txt 檔案必須包含 Python 適用的 Functions Framework 做為依附元件:

functions-framework==3.*

main.py 檔案中的程式碼必須定義函式進入點,並可照常匯入其他程式碼和外部依附元件。main.py 檔案也可以定義多個函式進入點,這些進入點可分別部署。

詳情請參閱 Python 執行階段總覽Python 適用的 Functions Framework

Go

Go 函式的基本目錄結構如下:

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

函式必須位於專案根目錄的 Go 封裝中。套件及其來源檔案可以有任何名稱,但函式不得位於 package main 中。如果您需要 main 套件 (例如用於本機測試),可以在子目錄中建立:

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

您的 go.mod 檔案必須包含 Go 適用的 Functions Framework 做為依附元件:

module example.com/my-module

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

根套件中的程式碼必須定義函式進入點,並可照常從子套件和依附元件匯入其他程式碼。您的套件也可以定義多個函式進入點,以便分別部署。

詳情請參閱「Go 執行階段總覽」和「Go 適用的 Functions Framework」。

Java

Java 函式的基本目錄結構如下:

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

Java 來源檔案必須位於 src/main/java/ 目錄下,且可使用任何名稱。如果來源檔案宣告套件,請在 src/main/java 下方新增一個目錄,並以套件名稱命名:

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

建議您將相關聯的測試放在 src/test/java/ 子目錄下。

pom.xml 檔案必須包含 Java 適用的 Functions Framework 做為依附元件:

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

原始碼檔案中的程式碼必須定義函式進入點,並可照常匯入其他程式碼和外部依附元件。來源檔案也可以定義多個函式進入點,以便分別部署。

詳情請參閱 Java 執行階段總覽Java 適用的 Functions Framework

.NET

.NET 函式的基本目錄結構如下:

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

您可以像處理其他 .NET 原始碼一樣建構專案。來源檔案可以有任何名稱。

專案檔案必須將 .NET 適用的 Functions Framework 納入為依附元件:

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

原始碼檔案中的程式碼必須定義函式進入點,並可照常匯入其他程式碼和外部依附元件。來源檔案也可以定義多個函式進入點,以便分別部署。

詳情請參閱 .NET 執行階段總覽.NET 適用的 Functions Framework

Ruby

Ruby 函式的基本目錄結構如下:

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

Cloud Run 會從函式目錄根層級名為 app.rb 的檔案載入原始碼。主要檔案必須命名為 app.rb

您的 Gemfile 檔案必須包含 Ruby 適用的函式架構做為依附元件:

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

app.rb 檔案中的程式碼必須定義函式進入點,並可照常匯入其他程式碼和外部依附元件。app.rb 檔案也可以定義多個函式進入點,這些進入點可分別部署。

詳情請參閱 Ruby 執行階段總覽Ruby 適用的 Functions Framework

PHP

PHP 函式的基本目錄結構如下:

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

Cloud Run 會從函式目錄根層級名為 index.php 的檔案載入原始碼。主要檔案必須命名為 index.php

composer.json 檔案必須包含 PHP 適用的 Functions Framework 做為依附元件:

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

index.php 檔案中的程式碼必須定義函式進入點,並可照常匯入其他程式碼和外部依附元件。index.php 檔案也可以定義多個函式進入點,這些進入點可個別部署。

詳情請參閱 PHP 執行階段總覽PHP 適用的 Functions Framework

如果將多個函式分組到單一專案中,請注意,每個函式最後可能會共用同一組依附元件。不過,部分函式可能不需要所有依附元件。

如有可能,建議您將大型多功能程式碼庫分割開來,並將每個函式放在自己的頂層目錄中 (如上述範例所示),且各自擁有自己的來源和專案設定檔。這種做法可盡量減少特定函式所需的依附元件數量,進而減少函式所需的記憶體容量。

編寫 HTTP 函式

如要透過 HTTP(S) 要求叫用函式,請編寫 HTTP 函式。如要允許 HTTP 語意,請使用 Function Framework 並指定 HTTP 函式簽章,接受 HTTP 專屬引數。

以下範例顯示各個執行階段的基本 HTTP 函式來源檔案。如需完整的工作範例,請參閱「使用 Google Cloud CLI 部署 Cloud Run 函式」。如要進一步瞭解來源程式碼的位置,請參閱「來源目錄結構」。

Node.js

ES 模組

  import { http } from '@google-cloud/functions-framework';
  http('myHttpFunction', (req, res) => {
    // Your code here

    // Send an HTTP response
    res.send('OK');
  });

package.json 檔案中新增下列依附元件,包括 "type": "module"

  {
    "dependencies": {
      "@google-cloud/functions-framework": "^3.0.0"
    },
    "type": "module"
  }

CommonJS 模組

  const functions = require('@google-cloud/functions-framework');

  // Register an HTTP function with the Functions Framework
  functions.http('myHttpFunction', (req, res) => {
    // Your code here

    // Send an HTTP response
    res.send('OK');
  });

package.json 檔案中新增下列依附元件:

  {
    "dependencies": {
      "@google-cloud/functions-framework": "^3.0.0"
    }
  }

在 Node.js 中,您可以使用 Node.js 適用的 Functions Framework 註冊 HTTP 處理常式函式。HTTP 處理常式函式必須是 Express 中介軟體函式,可接受 requestresponse 引數,並傳送 HTTP 回應。

Cloud Run 會根據要求的 Content-Type 標頭,使用 body-parser 自動剖析要求主體,因此您可以在 HTTP 處理常式中存取 req.bodyreq.rawBody 物件。

函式進入點是處理常式向 Functions Framework 註冊的名稱。在本範例中,進入點為 myHttpFunction

Python

import functions_framework

# Register an HTTP function with the Functions Framework
@functions_framework.http
def my_http_function(request):
  # Your code here

  # Return an HTTP response
  return 'OK'

在 Python 中,您可以使用 Python 適用的 Functions Framework 註冊 HTTP 處理常式函式。HTTP 處理常式函式必須接受 Flask 要求物件做為引數,並傳回 Flask 可轉換為 HTTP 回應物件的值

函式進入點是處理常式向 Functions Framework 註冊的名稱。在本範例中,進入點為 my_http_function

Go

package myhttpfunction

import (
    "fmt"
    "net/http"

    "github.com/GoogleCloudPlatform/functions-framework-go/functions"
)

func init() {
    // Register an HTTP function with the Functions Framework
    functions.HTTP("MyHTTPFunction", myHTTPFunction)
}

// Function myHTTPFunction is an HTTP handler
func myHTTPFunction(w http.ResponseWriter, r *http.Request) {
    // Your code here

    // Send an HTTP response
    fmt.Fprintln(w, "OK")
}

在 Go 中,您可以在 init() 函式中,使用 Go 適用的 Functions Framework 註冊 HTTP 處理常式函式。HTTP 處理常式函式必須使用標準 http.HandlerFunc 介面傳送 HTTP 回應。

函式進入點是處理常式向 Functions Framework 註冊的名稱。在本範例中,進入點為 MyHTTPFunction

HTTP 處理常式函式必須實作標準 http.HandlerFunc 介面。這個函式會接受 http.ResponseWriter 介面,函式會使用這個介面建立要求的回覆,以及指向 http.Request 結構體的指標,其中包含傳入 HTTP 要求的詳細資料。

Java

package myhttpfunction;

import com.google.cloud.functions.HttpFunction;
import com.google.cloud.functions.HttpRequest;
import com.google.cloud.functions.HttpResponse;

// Define a class that implements the HttpFunction interface
public class MyHttpFunction implements HttpFunction {
  // Implement the service() method to handle HTTP requests
  @Override
  public void service(HttpRequest request, HttpResponse response) throws Exception {
    // Your code here

    // Send an HTTP response
    response.getWriter().write("OK");
  }
}

在 Java 中,您可以使用 Functions Framework Java API,透過 HttpFunction 介面實作 HTTP 處理常式類別。service() 方法必須傳送 HTTP 回應。

函式進入點是 HTTP 處理常式類別的完整名稱,包括套件名稱。在本範例中,進入點為 myhttpfunction.MyHttpFunction

您的 service 方法會收到 HttpRequest 物件,其中說明傳入的 HTTP 要求,以及 HttpResponse 物件,您的函式會填入回應訊息。

.NET

using Google.Cloud.Functions.Framework;
using Microsoft.AspNetCore.Http;
using System.Threading.Tasks;

namespace MyProject
{
    // Define a class that implements the IHttpFunction interface
    public class MyHttpFunction : IHttpFunction
    {
        // Implement the HandleAsync() method to handle HTTP requests
        public async Task HandleAsync(HttpContext context)
        {
            // Your code here

            // Send an HTTP response
            await context.Response.WriteAsync("OK");
        }
    }
}

在 .NET 執行階段中,您可以使用 .NET 適用的 Functions Framework,透過 IHttpFunction 介面實作 HTTP 處理常式類別。HandleAsync() 方法會接受標準 ASP.NET HttpContext 物件做為引數,且必須傳送 HTTP 回應。

函式進入點是 HTTP 處理常式類別的完整名稱,包括命名空間。在本範例中,進入點為 MyProject.MyHttpFunction

Ruby

require "functions_framework"

# Register an HTTP function with the Functions Framework
FunctionsFramework.http "my_http_function" do |request|
  # Your code here

  # Return an HTTP response
  "OK"
end

在 Ruby 中,您可以使用 Ruby 適用的 Functions Framework 註冊 HTTP 處理常式函式。您的 HTTP 處理常式函式必須接受 Rack 要求物件做為引數,並傳回可用於 HTTP 回應的值

函式進入點是處理常式向 Functions Framework 註冊的名稱。在本範例中,進入點為 my_http_function

PHP

<?php

use Google\CloudFunctions\FunctionsFramework;
use Psr\Http\Message\ServerRequestInterface;

// Register an HTTP function with the Functions Framework
FunctionsFramework::http('myHttpFunction', 'myHttpHandler');

// Define your HTTP handler
function myHttpHandler(ServerRequestInterface $request): string
{
    // Your code here

    // Return an HTTP response
    return 'OK';
}

在 PHP 中,您可以使用 PHP 適用的 Functions Framework 註冊 HTTP 處理常式函式。HTTP 處理常式函式必須接受實作 PSR-7 ServerRequestInterface 介面的引數,並以字串或實作 PSR-7 ResponseInterface 介面的物件形式,傳回 HTTP 回應。

函式進入點是處理常式向 Functions Framework 註冊的名稱。在本範例中,進入點為 myHttpFunction

HTTP 要求和回應

使用 Functions Framework 註冊 HTTP 處理常式函式時,HTTP 處理常式可以檢查要求方法,並根據方法執行不同動作。

將事件供應商設為傳送 HTTP 要求至 Cloud Run 函式時,函式會傳送 HTTP 回應。如果函式建立背景工作 (例如使用執行緒、Future、JavaScript Promise 物件、回呼或系統程序),您必須先終止或解決這些工作,才能傳送 HTTP 回應。在傳送 HTTP 回應前未終止的任何工作可能無法完成,且可能導致未定義的行為。

處理 CORS

跨源資源共享 (CORS) 可讓在一個網域執行的應用程式存取另一個網域的資源。舉例來說,您可能需要允許網域向 Cloud Run 函式網域發出要求,才能存取函式。

如要允許對函式提出跨來源要求,請在 HTTP 回應中適當設定 Access-Control-Allow-Origin 標頭。對於預檢跨來源要求,您必須以 204 回應代碼和額外標頭,回應預檢 OPTIONS 要求。

Node.js

const functions = 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 3600s

  res.set('Access-Control-Allow-Origin', '*');

  if (req.method === 'OPTIONS') {
    // Send response to OPTIONS requests
    res.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

import functions_framework

@functions_framework.http
def cors_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 request
    if request.method == "OPTIONS":
        # Allows GET requests from any origin with the Content-Type
        # header and caches preflight response for an 3600s
        headers = {
            "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 request
    headers = {"Access-Control-Allow-Origin": "*"}

    return ("Hello World!", 200, headers)

Go


// Package http provides a set of HTTP Cloud Functions samples.
package http

import (
	"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.
func CORSEnabledFunction(w http.ResponseWriter, r *http.Request) {
	// Set CORS headers for the preflight request
	if r.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!")
}

func init() {
	functions.HTTP("CORSEnabledFunction", CORSEnabledFunction)
}

Java


import com.google.cloud.functions.HttpFunction;
import com.google.cloud.functions.HttpRequest;
import com.google.cloud.functions.HttpResponse;
import java.io.BufferedWriter;
import java.io.IOException;
import java.net.HttpURLConnection;

public class CorsEnabled implements HttpFunction {
  // 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.
  @Override
  public void service(HttpRequest request, HttpResponse response)
      throws IOException {
    // Set CORS headers
    //   Allows GETs from any origin with the Content-Type
    //   header and caches preflight response for 3600s
    response.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.
    BufferedWriter writer = response.getWriter();
    writer.write("CORS headers set successfully!");
  }
}

.NET

using Google.Cloud.Functions.Framework;
using Microsoft.AspNetCore.Http;
using System.Net;
using System.Threading.Tasks;

namespace Cors;

// For more information about CORS and CORS preflight requests, see
// https://developer.mozilla.org/en-US/docs/Glossary/Preflight_request.
public class Function : IHttpFunction
{
    public async Task HandleAsync(HttpContext context)
    {
        HttpRequest request = context.Request;
        HttpResponse response = context.Response;

        // Set CORS headers
        //   Allows GETs from any origin with the Content-Type
        //   header and caches preflight response for 3600s

        response.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;
        }

        await response.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 request
  if request.options?
    # Allows GET requests from any origin with the Content-Type
    # header and caches preflight response for an 3600s
    headers = {
      "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 request
    headers = {
      "Access-Control-Allow-Origin" => "*"
    }

    [200, headers, ["Hello World!"]]
  end
end

PHP


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!');
    }
}

如果 CORS 設定不正確,可能會看到下列錯誤:

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 限制

對於預檢的跨來源要求,預檢 OPTIONS 要求會在沒有 Authorization 標頭的情況下傳送,因此會在所有需要驗證的 HTTP 函式中遭到拒絕。由於預檢要求失敗,主要要求也會失敗。如要解決這項限制,請使用下列其中一個選項:

編寫事件導向函式

如要讓函式直接回應 Google Cloud 專案中的事件 (例如 Pub/Sub 主題上的訊息或 Cloud Storage 值區中的變更),請撰寫事件驅動函式。

事件導向函式是以 CloudEvents 為基礎,這是描述事件資料的業界標準規格。如要進一步瞭解 CloudEvents 規格,請前往 CloudEvents GitHub 存放區。CloudEvents 專案也提供一組 CloudEvents SDK,協助您在程式碼中使用 CloudEvents 物件。

以下範例顯示各個執行階段的事件驅動函式來源檔案。如要瞭解原始碼的位置,請參閱「來源目錄結構」。

Node.js

ES 模組

  import { cloudEvent } from "@google-cloud/functions-framework";
  cloudEvent('myCloudEventFunction', cloudEvent => {
    // Your code here
    // Access the CloudEvent data payload using cloudEvent.data
  });

package.json 檔案中新增下列依附元件,包括 "type": "module"

  {
    "dependencies": {
      "@google-cloud/functions-framework": "^3.0.0"
    },
    "type": "module"
  }

CommonJS 模組

const functions = require('@google-cloud/functions-framework');

// Register a CloudEvent function with the Functions Framework
functions.cloudEvent('myCloudEventFunction', cloudEvent => {
  // Your code here
  // Access the CloudEvent data payload using cloudEvent.data
});

package.json 檔案中新增下列依附元件:

  {
    "dependencies": {
      "@google-cloud/functions-framework": "^3.0.0"
    }
  }

在 Node.js 中,您可以使用 Node.js 適用的 Functions Framework 註冊 CloudEvent 處理常式函式。處理常式函式必須接受 CloudEvent 物件做為引數。

函式進入點是處理常式向 Functions Framework 註冊的名稱。在本範例中,進入點為 myCloudEventFunction

Python

import functions_framework

# Register a CloudEvent function with the Functions Framework
@functions_framework.cloud_event
def my_cloudevent_function(cloud_event):
  # Your code here
  # Access the CloudEvent data payload via cloud_event.data

在 Python 中,您可以使用 Python 適用的 Functions Framework 註冊 CloudEvent 處理常式函式。處理常式函式必須接受 CloudEvent 物件做為引數。

函式進入點是向 Functions Framework 註冊的處理常式函式名稱。在本範例中,進入點為 my_cloudevent_function

Go

package mycloudeventfunction

import (
    "context"

    "github.com/GoogleCloudPlatform/functions-framework-go/functions"
    "github.com/cloudevents/sdk-go/v2/event"
)

func init() {
    // Register a CloudEvent function with the Functions Framework
    functions.CloudEvent("MyCloudEventFunction", myCloudEventFunction)
}

// Function myCloudEventFunction accepts and handles a CloudEvent object
func myCloudEventFunction(ctx context.Context, e event.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 error
    if err != nil {
        // Append error message to log
        return err
    }

    // Return nil if no error occurred
    return nil
}

在 Go 中,您可以使用 Go 適用的 Functions Framework 註冊 CloudEvent 處理常式函式。處理常式函式必須接受 CloudEvents event.Event 物件做為引數。

函式進入點是處理常式向 Functions Framework 註冊的名稱。在本範例中,進入點為 MyCloudEventFunction

Java

package mycloudeventfunction;

import com.google.cloud.functions.CloudEventsFunction;
import io.cloudevents.CloudEvent;

// Define a class that implements the CloudEventsFunction interface
public class MyCloudEventFunction implements CloudEventsFunction {
  // Implement the accept() method to handle CloudEvents
  @Override
  public void accept(CloudEvent event) {
    // 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())
  }
}

在 Java 中,您可以使用 Functions Framework Java API,透過 CloudEventsFunction 介面實作 CloudEvent 處理常式類別。accept() 方法必須接受 CloudEvent 物件做為引數,並對事件執行任何處理作業。

函式進入點是 CloudEvent 處理常式類別的完整名稱,包括套件名稱。在本範例中,進入點為 mycloudeventfunction.MyCloudEventFunction

.NET

using CloudNative.CloudEvents;
using Google.Cloud.Functions.Framework;
using System.Threading;
using System.Threading.Tasks;

namespace MyProject
{
  // Define a class that implements the ICloudEventFunction<T> interface
  public class MyCloudEventFunction : ICloudEventFunction<CloudEventDataType>
  {
      // Implement the HandleAsync() method to handle CloudEvents
      public Task HandleAsync(CloudEvent cloudEvent, CloudEventDataType data, CancellationToken cancellationToken)
      {
          // Your code here
          // The data argument represents the CloudEvent data payload

          // Signal function completion
          return Task.CompletedTask;
      }
  }
}

在 .NET 執行階段中,您可以使用 .NET 適用的 Functions Framework,透過 ICloudEventFunction<T> 介面實作 CloudEvent 處理常式類別。HandleAsync() 方法會接受 CloudEvent 物件和相關聯的 CloudEvent 資料酬載做為引數。

範例程式碼中顯示的 CloudEvent 資料酬載引數類型 (CloudEventDataType),必須對應函式處理的事件類型。Google CloudEvents .NET 程式庫提供 Google 支援的各種事件資料類型。

函式進入點是 CloudEvent 處理常式類別的完整名稱,包括命名空間。在本範例中,進入點為 MyProject.MyCloudEventFunction

Ruby

require "functions_framework"

# Register a CloudEvent function with the Functions Framework
FunctionsFramework.cloud_event "my_cloudevent_function" do |cloud_event|
  # Your code here
  # Access the CloudEvent data payload via cloud_event.data
end

在 Ruby 中,您可以使用 Ruby 適用的 Functions Framework 註冊 CloudEvent 處理常式函式。處理常式函式必須接受 CloudEvents Event 物件做為引數。

函式進入點是處理常式向 Functions Framework 註冊的名稱。在本範例中,進入點為 my_cloudevent_function

PHP

<?php

use CloudEvents\V1\CloudEventInterface;
use Google\CloudFunctions\FunctionsFramework;

// Register a CloudEvent function with the Functions Framework
FunctionsFramework::cloudEvent('myCloudEventFunction', 'myCloudEventHandler');

// Define your CloudEvent handler
function myCloudEventHandler(CloudEventInterface $event): void
{
    // Your code here
    // Access the CloudEvent data payload using $event->getData()
}

在 PHP 中,您可以使用 PHP 適用的 Functions Framework 註冊 CloudEvent 處理常式函式。處理常式函式必須接受符合 CloudEventInterface 介面的引數。

函式進入點是處理常式向 Functions Framework 註冊的名稱。在本範例中,進入點為 myCloudEventFunction

如果是事件驅動函式,事件資料會以 CloudEvents 格式傳遞至函式,並包含與觸發函式的事件類型相應的 CloudEvent 資料酬載。如要瞭解支援的觸發條件、事件類型和相關聯的事件資料格式,請參閱「函式觸發條件」。

Google Events 存放區包含的資源,可用於處理 Google 發布的 CloudEvents。

函式終止

Cloud Run 會在函式傳回時,將事件驅動函式執行視為完成。如果函式會建立背景工作 (例如使用執行緒、Future、JavaScript Promise 物件、回呼或系統程序),您必須在函式傳回前終止或解決這些工作。函式傳回前未終止的任何工作可能無法完成,且可能導致未定義的行為。

自動重試

您可以設定事件驅動函式,在呼叫失敗時自動重試。詳情請參閱「重試事件驅動函式」。

後續步驟