直接调用 Cloud Run functions 函数

为了支持快速迭代和调试,Cloud Run functions 在命令行界面中提供了一个 call 命令,并在 Google Cloud 控制台界面中提供了测试功能。这样,您就可以直接调用函数,确保其行为符合预期。在这种情况下,函数会立即执行,即使它可能是为响应特定事件而部署的也是如此。

使用 Google Cloud CLI 测试函数

如需使用 gcloud CLI 直接调用函数,请使用 gcloud functions call 命令,并在 --data 参数中以 JSON 格式提供函数所需的任何数据。例如:

gcloud functions call YOUR_FUNCTION_NAME \
  --region=REGION --gen2 \
  --data '{"name":"Kalani"}'

您需要进行如下替换:

  • YOUR_FUNCTION_NAME:要测试的函数的名称
  • REGION:函数部署到的 Google Cloud 区域

--data 是发送给您的函数的参数,如下所示:

  • 对于 HTTP 函数,您提供的数据将以 POST 请求正文的形式发送。
  • 对于 CloudEvent 函数,数据将以事件数据形式直接传递给您的函数。

如需了解详情,请参阅 gcloud functions call 文档。

使用 Google Cloud Console 测试函数

如需通过 Google Cloud 控制台直接调用函数,请按以下步骤操作:

  1. 前往 Cloud Run functions 概览页面

  2. 从列表中点击要调用的函数的名称。 此时将转到函数详情 (Function details) 页面。

  3. 点击测试标签。

  4. 配置触发事件字段中,以 JSON 格式输入函数所需的任何数据。

  5. 点击 +Add query parameter(添加查询参数)和 +Add header parameter(添加标头参数),根据需要向函数调用添加查询参数和标头参数。

    Google Cloud 控制台中的 CLI 测试命令窗口会将您指定的参数组装成 gcloud functions call 命令。

  6. 选择在 Cloud Shell 中运行,打开 Cloud Shell 窗口以运行此命令。

  7. 在 Cloud Shell 窗口中显示 gcloud functions call 命令后,按 Enter 键触发该命令。

Cloud Pub/Sub 事件驱动的函数示例

本示例演示了如何直接调用由 Cloud Pub/Sub 事件触发的事件驱动函数:

Node.js

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

// Register a CloudEvent callback with the Functions Framework that will
// be executed when the Pub/Sub trigger topic receives a message.
functions.cloudEvent('helloPubSub', cloudEvent => {
  // The Pub/Sub message is passed as the CloudEvent's data payload.
  const base64name = cloudEvent.data.message.data;

  const name = base64name
    ? Buffer.from(base64name, 'base64').toString()
    : 'World';

  console.log(`Hello, ${name}!`);
});

Python

import base64

from cloudevents.http import CloudEvent
import functions_framework


# Triggered from a message on a Cloud Pub/Sub topic.
@functions_framework.cloud_event
def subscribe(cloud_event: CloudEvent) -> None:
    # Print out the data from Pub/Sub, to prove that it worked
    print(
        "Hello, " + base64.b64decode(cloud_event.data["message"]["data"]).decode() + "!"
    )

Go


// Package helloworld provides a set of Cloud Functions samples.
package helloworld

import (
	"context"
	"fmt"
	"log"

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

func init() {
	functions.CloudEvent("HelloPubSub", helloPubSub)
}

// MessagePublishedData contains the full Pub/Sub message
// See the documentation for more details:
// https://cloud.google.com/eventarc/docs/cloudevents#pubsub
type MessagePublishedData struct {
	Message PubSubMessage
}

// PubSubMessage is the payload of a Pub/Sub event.
// See the documentation for more details:
// https://cloud.google.com/pubsub/docs/reference/rest/v1/PubsubMessage
type PubSubMessage struct {
	Data []byte `json:"data"`
}

// helloPubSub consumes a CloudEvent message and extracts the Pub/Sub message.
func helloPubSub(ctx context.Context, e event.Event) error {
	var msg MessagePublishedData
	if err := e.DataAs(&msg); err != nil {
		return fmt.Errorf("event.DataAs: %w", err)
	}

	name := string(msg.Message.Data) // Automatically decoded from base64.
	if name == "" {
		name = "World"
	}
	log.Printf("Hello, %s!", name)
	return nil
}

Java

import com.google.cloud.functions.CloudEventsFunction;
import com.google.gson.Gson;
import functions.eventpojos.PubSubBody;
import io.cloudevents.CloudEvent;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.logging.Logger;

public class SubscribeToTopic implements CloudEventsFunction {
  private static final Logger logger = Logger.getLogger(SubscribeToTopic.class.getName());

  @Override
  public void accept(CloudEvent event) {
    // The Pub/Sub message is passed as the CloudEvent's data payload.
    if (event.getData() != null) {
      // Extract Cloud Event data and convert to PubSubBody
      String cloudEventData = new String(event.getData().toBytes(), StandardCharsets.UTF_8);
      Gson gson = new Gson();
      PubSubBody body = gson.fromJson(cloudEventData, PubSubBody.class);
      // Retrieve and decode PubSub message data
      String encodedData = body.getMessage().getData();
      String decodedData =
          new String(Base64.getDecoder().decode(encodedData), StandardCharsets.UTF_8);
      logger.info("Hello, " + decodedData + "!");
    }
  }
}

C#

using CloudNative.CloudEvents;
using Google.Cloud.Functions.Framework;
using Google.Events.Protobuf.Cloud.PubSub.V1;
using Microsoft.Extensions.Logging;
using System.Threading;
using System.Threading.Tasks;

namespace HelloPubSub;

public class Function : ICloudEventFunction<MessagePublishedData>
{
    private readonly ILogger _logger;

    public Function(ILogger<Function> logger) =>
        _logger = logger;

    public Task HandleAsync(CloudEvent cloudEvent, MessagePublishedData data, CancellationToken cancellationToken)
    {
        string nameFromMessage = data.Message?.TextData;
        string name = string.IsNullOrEmpty(nameFromMessage) ? "world" : nameFromMessage;
        _logger.LogInformation("Hello {name}", name);
        return Task.CompletedTask;
    }
}

Ruby

require "functions_framework"
require "base64"

FunctionsFramework.cloud_event "hello_pubsub" do |event|
  # The event parameter is a CloudEvents::Event::V1 object.
  # See https://cloudevents.github.io/sdk-ruby/latest/CloudEvents/Event/V1.html
  name = Base64.decode64 event.data["message"]["data"] rescue "World"

  # A cloud_event function does not return a response, but you can log messages
  # or cause side effects such as sending additional events.
  logger.info "Hello, #{name}!"
end

PHP


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

// Register the function with Functions Framework.
// This enables omitting the `FUNCTIONS_SIGNATURE_TYPE=cloudevent` environment
// variable when deploying. The `FUNCTION_TARGET` environment variable should
// match the first parameter.
FunctionsFramework::cloudEvent('helloworldPubsub', 'helloworldPubsub');

function helloworldPubsub(CloudEventInterface $event): void
{
    $log = fopen(getenv('LOGGER_OUTPUT') ?: 'php://stderr', 'wb');

    $cloudEventData = $event->getData();
    $pubSubData = base64_decode($cloudEventData['message']['data']);

    $name = $pubSubData ? htmlspecialchars($pubSubData) : 'World';
    fwrite($log, "Hello, $name!" . PHP_EOL);
}

如需直接调用该函数,请以事件数据的形式发送 PubsubMessage,该消息应为采用 base64 编码的数据:

Node.js

DATA=$(printf 'Hello!'|base64) && gcloud functions call helloPubSub --data '{"data":"'$DATA'"}'

Python

DATA=$(printf 'Hello!'|base64) && gcloud functions call hello_pubsub --data '{"data":"'$DATA'"}'

Go

DATA=$(printf 'Hello!'|base64) && gcloud functions call HelloPubSub --data '{"data":"'$DATA'"}'

Java

DATA=$(printf 'Hello!'|base64) && gcloud functions call java-hello-pubsub --data '{"data":"'$DATA'"}'

C#

DATA=$(printf 'Hello!'|base64) && gcloud functions call csharp-hello-pubsub --data '{"data":"'$DATA'"}'

Ruby

DATA=$(printf 'Hello!'|base64) && gcloud functions call hello_pubsub --data '{"data":"'$DATA'"}'

PHP

DATA=$(printf 'Hello!'|base64) && gcloud functions call helloworldPubsub --data '{"data":"'$DATA'"}'

此 CLI 示例使用 bashsh 语法。它适用于 Linux 和 Mac 环境,但不适用于 Windows。

您还可以从 Google Cloud 控制台调用该函数,只需在触发事件字段中使用相同的事件数据即可。