在本機開發函式

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

在 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 支援的兩種函式。所有語言執行階段都支援 httpcloudevent 簽章類型。

函式類型 簽章類型 說明 支援的執行階段
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)

Ruby

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.xmlbuild.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

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 檔案,如 Go 適用的 Functions Framework 網站所述。

cd cmd
go build
./cmd

使用環境變數:

cd cmd
go build
PORT=8080 ./cmd

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

Ruby

使用指令列引數:

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/SubCloud 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"
      }'
    

後續步驟