本機函式開發

Cloud Run 函式支援多種方法,可在目標部署環境外執行函式。這種做法在疊代式開發作業中特別實用,也適用於您想在部署前測試函式時。

不必部署即可執行函式,可簡化本機測試、遵守資料位置限制,以及多雲部署:

  • 資料所在地限制:在本機測試您的函式,但不存取實際資料,以免違反貴機構的資料所在地規則。

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

使用 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 函式架構程式庫做為依附元件,建立新的.NET 函式程式碼集:

# HTTP functions
dotnet new gcf-http

# CloudEvent functions
dotnet new gcf-event

Ruby

在 Ruby 中,您必須將雲端函式架構新增至函式的依附元件,才能將函式部署至 Cloud Run:

bundle add functions_framework

PHP

composer require google/cloud-functions-framework

設定 Functions Framework

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

支援的函式類型

Functions 架構支援 Cloud Run 函式支援的兩種函式類型。所有語言執行階段都支援 httpcloudevent 簽章類型。

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

指定要執行的函式

使用函式架構執行函式前,您必須先指定要執行程式碼中的哪個函式。針對大多數語言,您可以指定目標函式的名稱,如以下表格所示。請注意,此規則不適用於 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 函式架構可讓您將函式名稱和簽章類型指定為指令列引數或環境變數

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

"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 函式架構可讓您將函式名稱和簽名類型指定為指令列引數或環境變數執行架構時,必須指定指令列引數。

Go

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

Java

Java 函式架構會接受來自三個不同來源的設定資料,優先順序如下 (從最具體到最不具體):

  • 指令列引數
  • 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 標記類似,但兩者的 buildfile 子句卻大不相同。

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 函式架構會自動偵測函式。

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

Ruby

您可以使用 Ruby 函式架構,將函式名稱和簽名類型指定為指令列引數或環境變數執行架構時,必須指定指令列引數。

PHP

PHP 函式架構可讓您將環境變數設為指令列引數。

您也可以在 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

請先按照 Go 函式架構 網站的說明建立 cmd/main.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 值。以下指令說明如何執行 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 替換為函式名稱。

呼叫本機執行的函式

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

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

HTTP 函式

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

使用 Cloud Shell 測試 HTTP 函式

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

瀏覽器

按一下 Cloud Shell 工具列上的 網頁預覽功能按鈕 圖示,然後選擇「port 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"
      }'
    

後續步驟