在本機開發函式

Cloud Run functions 支援多種方法,可在目標部署環境之外執行函式,特別適用於疊代開發,以及在部署前測試函式。

函式不必部署即可執行,簡化了本機測試,以及多雲端部署作業,因此也能更簡單地遵循資料在地化限制:

  • 資料在地化限制:在本機測試函式,不必存取正式版資料,避免違反貴機構的資料在地化規則。

  • 多雲端部署:多雲端函式部署是既有的模式,可在極度重視可靠性的環境中,降低停機風險。將函式部署至 Cloud Run functions 以外的環境,亦可降低應用程式非預期停機的風險。

使用 Functions Framework 在本機開發函式

您可以使用 Functions Framework 在本機開發及測試函式。在本機開發函式有助於測試程式碼,不必重建函式容器。這可節省時間,並讓您更輕鬆地測試函式。

Cloud Run 會使用 Functions Framework 開放原始碼程式庫,將已部署的函式包裝在持續性 HTTP 應用程式中。

Functions Framework 還可在支援該語言的任何其他平台上執行,包括本機、地端部署伺服器和 Compute Engine。

安裝依附元件

在函式的目錄中,為您的語言安裝 Functions Framework 程式庫:

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

如果您使用 Maven,請將下方指令新增到 pom.xml 檔案中:

<dependency>
  <groupId>com.google.cloud.functions</groupId>
  <artifactId>functions-framework-api</artifactId>
  <version>1.1.0</version>
  <scope>provided</scope>
</dependency>

Gradle

如果您使用 Gradle,請將下方指令新增到 build.gradle 檔案中:

dependencies {
  // Every function needs this dependency to get the Functions Framework API.
  compileOnly 'com.google.cloud.functions:functions-framework-api:1.1.0'

  // To run function locally using Functions Framework's local invoker
  invoker 'com.google.cloud.functions.invoker:java-function-invoker:1.3.1'
}

詳情請參閱 Java Functions Framework 程式庫。

C#

下列指令會使用 .NET 範本,以 .NET Functions Framework 程式庫做為依附元件,建立新的.NET 函式程式碼集:

# HTTP functions
dotnet new gcf-http

# CloudEvent functions
dotnet new gcf-event

小茹

在 Ruby 中,您必須將 Functions Framework 新增至函式的依附元件,才能將函式部署到 Cloud Run:

bundle add functions_framework

PHP

composer require google/cloud-functions-framework

設定 Functions Framework

使用 Functions Framework 執行函式前,您需要先指定要執行的函式類型和名稱。這些屬性可以指定為指令列介面 (CLI) 旗標或環境變數。

支援的函式類型

Functions Framework 支援 Cloud Run functions 支援的兩種函式。所有語言執行階段都支援 http 和 cloudevent 簽章類型。

函式類型 簽章類型 說明 支援的執行階段
HTTP 觸發函式 http 接收及回應 HTTP 要求的函式。 所有執行階段
事件導向函式 cloudevent 業界標準事件格式。 所有執行階段

指定要執行的函式

使用 Functions Framework 執行函式前,您必須先指定要在程式碼內執行的函式。在大多數語言中,您可以指定目標函式的方法名稱,如下表所示 請注意,Java 和 .NET 執行階段是這項規則的例外狀況。

各語言的操作說明

如需各語言支援的設定選項清單,請參閱下表。

Node.js

CLI 引數 環境變數 說明
--port PORT 要監聽要求的通訊埠 (預設值:8080)
--target FUNCTION_TARGET 要叫用的 exported 函式名稱 (預設值:function)
--signature-type FUNCTION_SIGNATURE_TYPE 函式使用的簽章類型,可以是 http (預設值) 或 cloudevent。

Python

CLI 引數 環境變數 說明
--port PORT 要監聽要求的通訊埠 (預設值:8080)
--target FUNCTION_TARGET 要叫用的 exported 函式名稱 (預設值:function)
--signature-type FUNCTION_SIGNATURE_TYPE 函式使用的簽章類型,可以是 http (預設值) 或 cloudevent。

Go

環境變數 說明
PORT 要監聽要求的通訊埠 (預設值:8080)

Java

引數名稱 環境變數 說明
run.port PORT 要監聽要求的通訊埠 (預設值:8080)
run.functionTarget FUNCTION_TARGET 要叫用的 exported 函式名稱 (預設值:function)

C#

CLI 引數 環境變數 說明
--port PORT 要監聽要求的通訊埠 (預設值:8080)
--target (或僅限引數) FUNCTION_TARGET 要叫用的函式 classname (預設值:function)

小茹

CLI 引數 環境變數 說明
--port PORT 要監聽要求的通訊埠 (預設值:8080)
--target FUNCTION_TARGET 要叫用的 exported 函式名稱 (預設值:function)

PHP

環境變數 說明
FUNCTION_TARGET 要叫用的函式名稱 (預設值:function)
FUNCTION_SIGNATURE_TYPE 函式使用的簽章類型,可以是 http (預設值) 或 cloudevent。

請按照下列操作說明設定及執行 Functions Framework:

Node.js

Node.js Functions Framework 可讓您將函式名稱和簽章類型指定為指令列引數或環境變數。

您也可以在 package.json 建構檔案中指定這些值,方法是新增 start 指令碼,並加入必要的 CLI 引數,如下方範例所示。

"scripts": {
"start": "npx functions-framework --target=YOUR_FUNCTION_NAME [--signature-type=YOUR_SIGNATURE_TYPE]"
}

您也可以使用環境變數執行相同操作:

"scripts": {
"start": "FUNCTION_TARGET=YOUR_FUNCTION_NAME FUNCTION_SIGNATURE_TYPE=YOUR_SIGNATURE_TYPE npx functions-framework"
}

將 YOUR_FUNCTION_NAME 替換為函式的方法名稱,並將 YOUR_SIGNATURE_TYPE (如適用) 替換為函式的簽章類型,如「支援的函式類型」所示。

Python

Python Functions Framework 可讓您將函式名稱和簽章類型指定為指令列引數或環境變數。執行框架時,必須指定指令列引數。

Go

Go Functions Framework 會使用 funcframework.RegisterHTTPFunctionContext 指定函式目標和簽章類型。

Java

Java Functions Framework 會接受來自三種不同來源的設定資料,優先順序如下 (從最明確到最不明確):

  • 指令列引數
  • 建構檔案
  • 環境變數

指令列引數

Maven

如要指定想執行的函式,請在 mvn 指令中加入下列指令列介面 (CLI) 旗標:

-Drun.functionTarget=YOUR_FUNCTION_NAME

您也可以加入下列 CLI 旗標,以類似方式指定目標通訊埠:

-Drun.port=12345

Gradle

Gradle 的 CLI 旗標與 Maven 的旗標幾乎相同。Gradle 唯一會進行的變更,是將每個旗標開頭的 -D 替換成 -P,如下方範例所示:

# Maven version

-Drun.functionTarget=...

# Gradle version

-Prun.functionTarget=...

建構檔案

您也可以在專案的建構檔案中指定要執行的函式。Maven 和 Gradle 的 CLI 旗標很類似,但建構檔案子句的差異很大。

Maven

Maven 建構檔案名為 pom.xml,請在這個檔案中加入下列子句,指定目標函式:

<plugin>
  <groupId>com.google.cloud.functions</groupId>
  <artifactId>function-maven-plugin</artifactId>
  <version>0.11.0</version>
  <configuration>
    <functionTarget>functions.HelloWorld</functionTarget>
  </configuration>
</plugin>

將 <functionTarget> 替換成您的函式類別名稱 舉例來說,假設套件 functions 中的函式類別名稱為 HelloCloudFunctions,則類別名稱會是 functions.HelloCloudFunctions。這與上層建構檔案 (pom.xml 或 build.gradle) 相關。

Gradle

Gradle 建構檔案名為 build.gradle。請在這個檔案中加入下列子句,指定目標函式:

// Register a "runFunction" task to run the function locally
tasks.register("runFunction", JavaExec) {
  main = 'com.google.cloud.functions.invoker.runner.Invoker'
  classpath(configurations.invoker)
  inputs.files(configurations.runtimeClasspath, sourceSets.main.output)
  args(
    '--target', project.findProperty('run.functionTarget') ?: '',
    '--port', project.findProperty('run.port') ?: 8080
  )
  doFirst {
    args('--classpath', files(configurations.runtimeClasspath, sourceSets.main.output).asPath)
  }
}

C#

如果您使用 dotnet new 和上述其中一個範本建立專案,.NET Functions Framework 會自動偵測函式。

假如專案包含多個函式,請參閱「執行架構」一節,瞭解如何執行特定函式。

小茹

Ruby Functions Framework 可讓您將函式名稱和簽章類型指定為指令列引數或環境變數。執行框架時,必須指定指令列引數。

PHP

PHP Functions Framework 可讓您將環境變數指定為指令列引數。

您也可以在 composer.json 建構檔案中指定這些值,方法是新增 start 指令碼,如下方範例所示。

"scripts": {
 "start": [
     "Composer\\Config::disableProcessTimeout",
     "FUNCTION_TARGET=YOUR_FUNCTION_NAME php -S localhost:${PORT:-8080} vendor/bin/router.php"
].
}

將 YOUR_FUNCTION_NAME 替換為函式名稱,並將 YOUR_SIGNATURE_TYPE (如適用;本範例未包含此項) 替換為函式簽章類型。

執行函式

使用下列指令,透過 Functions Framework 執行函式。 除非您明確指定 PORT 值,否則函式預設會透過 localhost:8080 存取。

Node.js

npm start

Python

使用指令列引數:

functions-framework --target=YOUR_FUNCTION_NAME

使用環境變數:

FUNCTION_TARGET=YOUR_FUNCTION_NAME functions-framework

將 YOUR_FUNCTION_NAME 替換為函式的方法名稱。

Go

建立 cmd/main.go 檔案,定義 main 套件和 main() 函式,啟動本機 HTTP 伺服器,如 Go 適用的 Functions Framework 說明文件所述。

cd cmd
go build
FUNCTION_TARGET=YOUR_FUNCTION_NAME PORT=8080 ./cmd

將 YOUR_FUNCTION_NAME 替換為 Go 函式的名稱。

Java

Maven

使用下列指令執行 pom.xml 中指定的函式:

mvn function:run

使用下列指令執行指令列引數中指定的函式:

mvn function:run -Drun.functionTarget=YOUR_FUNCTION_NAME

使用下列指令執行指定為環境變數的函式:

FUNCTION_TARGET=YOUR_FUNCTION_NAME mvn function:run

將 YOUR_FUNCTION_NAME 替換為函式的類別名稱。

Gradle

使用下列指令執行 build.gradle 中指定的函式:

./gradlew runFunction

使用下列指令執行指令列引數中指定的函式:

./gradlew runFunction -Prun.functionTarget=YOUR_FUNCTION_NAME

使用下列指令執行指定為環境變數的函式:

FUNCTION_TARGET=YOUR_FUNCTION_NAME ./gradlew runFunction

將 YOUR_FUNCTION_NAME 替換為函式的類別名稱。

C#

如果目前的 .NET 專案中只有一個函式,請使用下列指令執行函式 請注意,這是範本所建立專案的預設結構。

dotnet run

如果 .NET 專案包含多個函式,請使用下列指令執行特定函式。另外,請將 YOUR_FUNCTION_CLASSNAME 替換為函式的類別名稱,包括命名空間。

dotnet run YOUR_FUNCTION_CLASSNAME

如要同時執行多個函式,就必須執行多個 Functions Framework 執行個體。為避免執行中的架構執行個體發生衝突,每個執行個體應使用不同的 PORT 值。以下指令顯示如何執行 PORT 值為 8080 的函式。

使用指令列引數:

dotnet run --target YOUR_FUNCTION_CLASSNAME --port 8080

使用環境變數:

FUNCTION_TARGET=YOUR_FUNCTION_CLASSNAME PORT=8080 dotnet run

小茹

使用指令列引數:

bundle exec functions-framework-ruby --target YOUR_FUNCTION_NAME

使用環境變數:

FUNCTION_TARGET=YOUR_FUNCTION_NAME bundle exec functions-framework-ruby

將 YOUR_FUNCTION_NAME 替換為函式的方法名稱。

PHP

export FUNCTION_TARGET=YOUR_FUNCTION_NAME
php -S localhost:8080 vendor/bin/router.php

將 YOUR_FUNCTION_NAME 替換為函式的名稱。

呼叫在本機執行的函式

本節的練習假設您已在 localhost 上設定在本機執行的函式,並使用 Functions Framework。

您可以透過本機服務程序傳送 HTTP 要求,藉此觸發在本機執行的函式。

HTTP 函式

從開發環境測試 HTTP 函式時,函式通常會監聽 localhost:8080 的要求。此介面只能從執行函式的機器或 VM 進行存取;從任何其他系統傳送的要求都無法存取。因此,您必須從執行函式的相同系統發出 HTTP 要求。在下列範例中,如果您函式監聽的通訊埠不是 8080,請將範例中的 8080 替換為函式的通訊埠號碼。

使用 Cloud Shell 測試 HTTP 函式

如果您要使用 Cloud Shell 建構並測試函式,請在 Cloud Shell 終端機視窗中以本機啟動函式,然後從瀏覽器或 curl 執行個體發出 HTTP 觸發要求,如下所示:

瀏覽器

按一下 Cloud Shell 工具列上的 網頁預覽按鈕 圖示,然後選擇「port 8080」(通訊埠 8080)或「Change port」(變更通訊埠),以選取其他通訊埠。系統會開啟正確系統的瀏覽器視窗,並對指定通訊埠發出 GET 要求。

Curl

如要控制 HTTP 要求的格式,或查看未格式化的回覆,請使用 curl:

  1. 按一下 Cloud Shell 選單列中的「+」圖示,在執行函式的相同系統上開啟新的終端機視窗。
  2. 在該視窗中執行 curl 指令以觸發函式。 例如:

    curl localhost:8080
    

在電腦伺服器上測試 HTTP 函式

如果您是在本機電腦系統上建構及執行函式,請先在本機啟動函式,然後從瀏覽器或 curl 執行個體發出 HTTP 觸發要求,如下所示:

瀏覽器

開啟新的瀏覽器視窗或分頁,然後在瀏覽器網址列中輸入 http://localhost:8080。這會在您的電腦伺服器上開啟前往 localhost:8080 的瀏覽器視窗,以觸發函式。

Curl

在本機電腦上開啟新的終端機視窗,然後在該視窗中執行 curl 指令,觸發函式。例如:

 curl localhost:8080

這會執行指定的 curl 指令來觸發函式,並顯示未格式化的回應。

事件導向函式

您可以使用 curl 將範例事件傳送至事件驅動函式。下列 curl 要求顯示如何將 Pub/Sub 和 Cloud Storage 範例事件傳送至在 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"
      }'
    

後續步驟