本機函式開發

Cloud Run functions 支援多種方法,可在目標部署環境以外執行函式。這項功能特別適合用於疊代開發,以及在部署函式前進行測試的情況。

您不必部署函式即可執行,這有助於簡化本機測試、遵守資料所在地限制,以及進行多雲端部署:

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

  • 多雲端部署:多雲端函式部署是已建立的模式,可降低可靠性至關重要的環境中發生停機的風險。將函式部署至 Cloud Run 函式以外的環境,可降低應用程式發生非預期停機的風險。

使用 Functions Framework 在本機開發函式

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

Cloud Run 會使用開放原始碼的函式架構程式庫,將部署的函式包裝在持續性 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 函式架構會使用 funcframework.RegisterHTTPFunctionContext 指定函式目標和簽章類型。

Java

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

  • 指令列引數
  • Buildfiles
  • 環境變數

指令列引數

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

Buildfiles

您也可以在專案的建構檔案中指定要執行的函式。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 適用的函式架構網站所述。

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 值。以下指令顯示如何使用 PORT8080 執行函式。

使用指令列引數:

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 改為函式名稱。

呼叫在本機執行的函式

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

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

HTTP 函式

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

使用 Cloud Shell 測試 HTTP 函式

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

瀏覽器

按一下 Cloud Shell 工具列上的 網頁預覽功能按鈕 圖示,然後選擇「通訊埠 8080」或「變更通訊埠」,即可選取其他通訊埠。這會在正確的系統上開啟瀏覽器視窗,並對指定通訊埠發出 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"
      }'
    

後續步驟