Escreva funções do Cloud Run

Esta página descreve como escrever funções do Cloud Run baseadas em HTTP e eventos com o Functions Framework.

Vista geral da Functions Framework

Quando escreve o código-fonte das funções, tem de usar o Functions Framework, uma biblioteca de código aberto para escrever funções do Cloud Run. Com o Functions Framework, pode escrever funções simples que são executadas no Cloud Run e noutros ambientes, incluindo a sua máquina de desenvolvimento local e ambientes baseados no Knative.

O Functions Framework permite-lhe:

  • Invocar uma função do Cloud Run em resposta a um pedido.
  • Desorganiza automaticamente eventos em conformidade com a especificação CloudEvents, uma especificação da indústria para descrever dados de eventos de forma comum.
  • Inicie um servidor de desenvolvimento local para testes.

O Functions Framework fornece uma interface para criar serviços modulares. Para usar o Functions Framework no seu código-fonte, especifique o seguinte:

Ponto de entrada da função

O código-fonte tem de definir um ponto de entrada da função, que é o código executado quando o Cloud Run invoca a sua função. Especifica este ponto de entrada quando implementa a sua função.

A forma como define o ponto de entrada depende do tempo de execução da linguagem que usa. Algumas linguagens usam uma função como ponto de entrada, enquanto outras usam uma classe.

Tipo de assinatura

Quando escreve o código fonte de uma função com o Functions Framework, tem de especificar um dos dois tipos de assinatura:

  • Funções HTTP: regista uma função de controlador HTTP. Use uma função HTTP quando a sua função precisar de um ponto final de URL e tiver de responder a pedidos HTTP, como para webhooks.
  • Funções acionadas por eventos, também conhecidas como funções CloudEvents: regista uma função de controlador CloudEvents. Use uma função acionada por eventos quando a sua função for acionada diretamente em resposta a eventos no seu Google Cloud projeto, como mensagens num tópico do Pub/Sub ou alterações num contentor do Cloud Storage.

Estrutura do diretório de origem

O Functions Framework é suportado em vários idiomas de programação. O tempo de execução da linguagem que escolher e o tipo de função que quer escrever determinam como estruturar o código e implementar a função.

Para que o Cloud Run localize a definição da sua função, cada tempo de execução de linguagem tem requisitos para estruturar o código-fonte.

Node.js

A estrutura de diretórios básica para funções do Node.js é a seguinte:

.
├── index.js
└── package.json

Por predefinição, o Cloud Run tenta carregar o código-fonte a partir de um ficheiro com o nome index.js na raiz do diretório da função. Para especificar um ficheiro de origem principal diferente, use o campo main no ficheiro package.json.

O ficheiro package.json também tem de incluir o Functions Framework para Node.js como dependência:

{
  "main": "index.js",
  "dependencies": {
    "@google-cloud/functions-framework": "^3.0.0"
  },
  "type": "module"
}

O código no ficheiro principal tem de definir o ponto de entrada da função e pode importar outro código e módulos Node.js. O ficheiro principal também pode definir vários pontos de entrada de funções que podem ser implementados separadamente.

Consulte a vista geral do tempo de execução do Node.js e a estrutura de funções para Node.js para ver mais detalhes.

Python

A estrutura de diretórios básica para funções Python é a seguinte:

.
├── main.py
└── requirements.txt

O Cloud Run carrega o código-fonte de um ficheiro denominado main.py na raiz do diretório da função. Tem de atribuir o nome main.py ao ficheiro principal.

O seu ficheiro requirements.txt tem de incluir o Functions Framework para Python como uma dependência:

functions-framework==3.*

O código no seu ficheiro main.py tem de definir o ponto de entrada da função e pode importar outro código e dependências externas normalmente. O ficheiro main.py também pode definir vários pontos de entrada de funções que podem ser implementados separadamente.

Consulte a descrição geral do tempo de execução do Python e o Functions Framework para Python para ver mais detalhes.

Ir

A estrutura de diretórios básica para funções Go é a seguinte:

.
├── myfunction.go
└── go.mod

A sua função tem de estar num pacote Go na raiz do seu projeto. O pacote e os respetivos ficheiros de origem podem ter qualquer nome, exceto que a função não pode estar em package main. Se precisar de um pacote main, por exemplo, para testes locais, pode criar um num subdiretório:

.
├── myfunction.go
├── go.mod
└── cmd/
  └── main.go

O seu ficheiro go.mod tem de incluir o Functions Framework para Go como dependência:

module example.com/my-module

require (
  github.com/GoogleCloudPlatform/functions-framework-go v1.5.2
)

O código no pacote raiz tem de definir o ponto de entrada da função e pode importar outro código de subpacotes e dependências como habitualmente. O seu pacote também pode definir vários pontos de entrada de funções que podem ser implementados separadamente.

Consulte a descrição geral do tempo de execução do Go e o Functions Framework para Go para ver mais detalhes.

Java

A estrutura de diretórios básica para funções Java é a seguinte:

.
├── pom.xml
└── src/
  └── main/
      └── java/
          └── MyFunction.java

Os seus ficheiros de origem Java têm de estar no diretório src/main/java/ e podem ter qualquer nome. Se os seus ficheiros de origem declararem um pacote, adicione um diretório adicional em src/main/java com o nome do pacote:

.
├── pom.xml
└── src/
  └── main/
      └── java/
          └── mypackage/
              └── MyFunction.java

Recomendamos que coloque os testes associados num subdiretório src/test/java/.

O seu ficheiro pom.xml tem de incluir o Functions Framework for Java como uma dependência:

...
    <dependency>
      <groupId>com.google.cloud.functions</groupId>
      <artifactId>functions-framework-api</artifactId>
      <version>1.0.4</version>
    </dependency>
...

O código nos ficheiros de origem tem de definir o ponto de entrada da função e pode importar outro código e dependências externas normalmente. Os ficheiros de origem também podem definir vários pontos de entrada de funções que podem ser implementados separadamente.

Consulte a descrição geral do tempo de execução Java e o Functions Framework para Java para ver mais detalhes.

.NET

A estrutura de diretórios básica para funções .NET é a seguinte:

.
├── MyFunction.cs
└── MyProject.csproj

Pode estruturar os seus projetos como faria com qualquer outro código fonte .NET. Os ficheiros de origem podem ter qualquer nome.

O ficheiro de projeto tem de incluir o Functions Framework para .NET como uma dependência:

...
    <PackageReference Include="Google.Cloud.Functions.Hosting" Version="1.0.0" />
...

O código nos ficheiros de origem tem de definir o ponto de entrada da função e pode importar outro código e dependências externas normalmente. Os ficheiros de origem também podem definir vários pontos de entrada de funções que podem ser implementados separadamente.

Consulte a descrição geral do tempo de execução do.NET e a estrutura de funções para .NET para mais detalhes.

Ruby

A estrutura de diretórios básica para funções Ruby é a seguinte:

.
├── app.rb
├── Gemfile
└── Gemfile.lock

O Cloud Run carrega o código-fonte de um ficheiro denominado app.rb na raiz do diretório da função. O ficheiro principal tem de ter o nome app.rb.

O seu ficheiro Gemfile tem de incluir o Functions Framework para Ruby como uma dependência:

source "https://rubygems.org"
gem "functions_framework", "~> 1.0"

O código no seu ficheiro app.rb tem de definir o ponto de entrada da função e pode importar outro código e dependências externas normalmente. O ficheiro app.rb também pode definir vários pontos de entrada de funções que podem ser implementados separadamente.

Consulte a descrição geral do tempo de execução do Ruby e a estrutura de funções para Ruby para ver mais detalhes.

PHP

A estrutura de diretórios básica para funções PHP é a seguinte:

.
├── index.php
└── composer.json

O Cloud Run carrega o código-fonte de um ficheiro denominado index.php na raiz do diretório da função. Tem de atribuir o nome index.php ao ficheiro principal.

O seu ficheiro composer.json tem de incluir o Functions Framework para PHP como uma dependência:

{
  "require": {
    "google/cloud-functions-framework": "^1.1"
  }
}

O código no seu ficheiro index.php tem de definir o seu ponto de entrada da função e pode importar outro código e dependências externas como habitualmente. O ficheiro index.php também pode definir vários pontos de entrada de funções que podem ser implementados separadamente.

Consulte a vista geral do tempo de execução do PHP e a estrutura de funções para PHP para ver mais detalhes.

Se agrupar várias funções num único projeto, tenha em atenção que cada função pode acabar por partilhar o mesmo conjunto de dependências. No entanto, algumas das funções podem não precisar de todas as dependências.

Sempre que possível, recomendamos que divida grandes bases de código multifuncionais e coloque cada função no seu próprio diretório de nível superior, conforme mostrado nos exemplos anteriores, com os seus próprios ficheiros de configuração de origem e de projeto. Esta abordagem minimiza o número de dependências necessárias para uma determinada função, o que, por sua vez, reduz a quantidade de memória de que a função precisa.

Escreva funções HTTP

Escreva uma função HTTP quando quiser invocar uma função através de um pedido HTTP(S). Para permitir a semântica HTTP, usa o Function Framework e especifica a assinatura da função HTTP para aceitar argumentos específicos de HTTP.

O exemplo seguinte mostra um ficheiro de origem de função HTTP básico para cada tempo de execução. Para ver um exemplo de funcionamento completo, consulte o artigo Implemente uma função do Cloud Run usando a CLI do Google Cloud. Para mais informações sobre onde encontrar o código-fonte, consulte a estrutura do diretório de origem.

Node.js

Módulo ES

  import { http } from '@google-cloud/functions-framework';
  http('myHttpFunction', (req, res) => {
    // Your code here

    // Send an HTTP response
    res.send('OK');
  });

Adicione as seguintes dependências, incluindo "type": "module" no ficheiro package.json:

  {
    "dependencies": {
      "@google-cloud/functions-framework": "^3.0.0"
    },
    "type": "module"
  }

Módulo CommonJS

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

  // Register an HTTP function with the Functions Framework
  functions.http('myHttpFunction', (req, res) => {
    // Your code here

    // Send an HTTP response
    res.send('OK');
  });

Adicione as seguintes dependências ao ficheiro package.json:

  {
    "dependencies": {
      "@google-cloud/functions-framework": "^3.0.0"
    }
  }

No Node.js, regista uma função de controlador HTTP com o Functions Framework para Node.js. A função do controlador HTTP tem de ser uma função de middleware do Express que aceite os argumentos request e response e envie uma resposta HTTP.

O Cloud Run analisa automaticamente o corpo do pedido com base no cabeçalho Content-Type do pedido através de body-parser, pelo que pode aceder aos objetos req.body e req.rawBody no seu controlador HTTP.

O ponto de entrada da função é o nome com o qual o controlador está registado no Functions Framework. Neste exemplo, o ponto de entrada é myHttpFunction.

Python

import functions_framework

# Register an HTTP function with the Functions Framework
@functions_framework.http
def my_http_function(request):
  # Your code here

  # Return an HTTP response
  return 'OK'

Em Python, regista uma função de controlador HTTP com o Functions Framework para Python. A função do controlador HTTP tem de aceitar um objeto Flask request como argumento e devolver um valor que o Flask possa converter num objeto de resposta HTTP.

O ponto de entrada da função é o nome com o qual o controlador está registado no Functions Framework. Neste exemplo, o ponto de entrada é my_http_function.

Ir

package myhttpfunction

import (
    "fmt"
    "net/http"

    "github.com/GoogleCloudPlatform/functions-framework-go/functions"
)

func init() {
    // Register an HTTP function with the Functions Framework
    functions.HTTP("MyHTTPFunction", myHTTPFunction)
}

// Function myHTTPFunction is an HTTP handler
func myHTTPFunction(w http.ResponseWriter, r *http.Request) {
    // Your code here

    // Send an HTTP response
    fmt.Fprintln(w, "OK")
}

Em Go, regista uma função de controlador HTTP com o Functions Framework para Go na sua função init(). A função do controlador HTTP tem de usar a interface http.HandlerFunc padrão para enviar uma resposta HTTP.

O ponto de entrada da função é o nome com o qual o controlador está registado no Functions Framework. Neste exemplo, o ponto de entrada é MyHTTPFunction.

A função do controlador HTTP tem de implementar a interface http.HandlerFunc padrão. Aceita uma interface http.ResponseWriter que a sua função usa para criar uma resposta ao pedido e um ponteiro para uma estrutura http.Request que contém os detalhes do pedido HTTP de entrada.

Java

package myhttpfunction;

import com.google.cloud.functions.HttpFunction;
import com.google.cloud.functions.HttpRequest;
import com.google.cloud.functions.HttpResponse;

// Define a class that implements the HttpFunction interface
public class MyHttpFunction implements HttpFunction {
  // Implement the service() method to handle HTTP requests
  @Override
  public void service(HttpRequest request, HttpResponse response) throws Exception {
    // Your code here

    // Send an HTTP response
    response.getWriter().write("OK");
  }
}

Em Java, usa a API Java do Functions Framework para implementar uma classe de controlador HTTP com a interface HttpFunction. O método service() tem de enviar uma resposta HTTP.

O ponto de entrada da função é o nome totalmente qualificado da classe do controlador HTTP, incluindo o nome do pacote. Neste exemplo, o ponto de entrada é myhttpfunction.MyHttpFunction.

O seu método service recebe um objeto HttpRequest que descreve o pedido HTTP de entrada e um objeto HttpResponse que a sua função preenche com uma mensagem de resposta.

.NET

using Google.Cloud.Functions.Framework;
using Microsoft.AspNetCore.Http;
using System.Threading.Tasks;

namespace MyProject
{
    // Define a class that implements the IHttpFunction interface
    public class MyHttpFunction : IHttpFunction
    {
        // Implement the HandleAsync() method to handle HTTP requests
        public async Task HandleAsync(HttpContext context)
        {
            // Your code here

            // Send an HTTP response
            await context.Response.WriteAsync("OK");
        }
    }
}

Nos runtimes .NET, usa o Functions Framework para .NET para implementar uma classe de controlador HTTP com a interface IHttpFunction. O método HandleAsync() aceita um objeto ASP.NET HttpContext padrão como argumento e tem de enviar uma resposta HTTP.

O ponto de entrada da função é o nome totalmente qualificado da classe do controlador HTTP, incluindo o espaço de nomes. Neste exemplo, o ponto de entrada é MyProject.MyHttpFunction.

Ruby

require "functions_framework"

# Register an HTTP function with the Functions Framework
FunctionsFramework.http "my_http_function" do |request|
  # Your code here

  # Return an HTTP response
  "OK"
end

Em Ruby, regista uma função de controlador HTTP com o Functions Framework para Ruby. A sua função de controlador HTTP tem de aceitar um objeto de pedido Rack como argumento e devolver um valor que possa ser usado como resposta HTTP.

O ponto de entrada da função é o nome com o qual o controlador está registado no Functions Framework. Neste exemplo, o ponto de entrada é my_http_function.

PHP

<?php

use Google\CloudFunctions\FunctionsFramework;
use Psr\Http\Message\ServerRequestInterface;

// Register an HTTP function with the Functions Framework
FunctionsFramework::http('myHttpFunction', 'myHttpHandler');

// Define your HTTP handler
function myHttpHandler(ServerRequestInterface $request): string
{
    // Your code here

    // Return an HTTP response
    return 'OK';
}

Em PHP, regista uma função de controlador HTTP com o Functions Framework para PHP. A sua função de controlador HTTP tem de aceitar um argumento que implemente a interface PSR-7 ServerRequestInterface e tem de devolver uma resposta HTTP como uma string ou um objeto que implemente a interface PSR-7 ResponseInterface.

O ponto de entrada da função é o nome com o qual o controlador está registado no Functions Framework. Neste exemplo, o ponto de entrada é myHttpFunction.

Pedidos e respostas HTTP

Quando regista uma função de controlador HTTP com o Functions Framework, o seu controlador HTTP pode inspecionar o método de pedido e realizar diferentes ações com base no método.

Quando configura um fornecedor de eventos para enviar pedidos HTTP para a sua função do Cloud Run, a função envia uma resposta HTTP. Se a função criar tarefas em segundo plano (como com threads, futuros, objetos de promessa JavaScript, callbacks ou processos do sistema), tem de terminar ou resolver estas tarefas antes de enviar uma resposta HTTP. As tarefas não terminadas antes de a resposta HTTP ser enviada podem não ser concluídas e podem causar um comportamento indefinido.

Processar CORS

A partilha de recursos de origem cruzada (CORS) é uma forma de permitir que as aplicações executadas num domínio acedam a recursos de outro domínio. Por exemplo, pode ter de permitir que o seu domínio faça pedidos ao domínio das funções do Cloud Run para aceder à sua função.

Para permitir pedidos de origem cruzada à sua função, defina o cabeçalho Access-Control-Allow-Origin conforme adequado na sua resposta HTTP. Para pedidos de origem cruzada de verificação prévia, tem de responder ao pedido OPTIONS de verificação prévia com um código de resposta 204 e cabeçalhos adicionais.

Node.js

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

/**
 * HTTP function that supports CORS requests.
 *
 * @param {Object} req Cloud Function request context.
 * @param {Object} res Cloud Function response context.
 */
functions.http('corsEnabledFunction', (req, res) => {
  // Set CORS headers for preflight requests
  // Allows GETs from any origin with the Content-Type header
  // and caches preflight response for 3600s

  res.set('Access-Control-Allow-Origin', '*');

  if (req.method === 'OPTIONS') {
    // Send response to OPTIONS requests
    res.set('Access-Control-Allow-Methods', 'GET');
    res.set('Access-Control-Allow-Headers', 'Content-Type');
    res.set('Access-Control-Max-Age', '3600');
    res.status(204).send('');
  } else {
    res.send('Hello World!');
  }
});

Python

import functions_framework

@functions_framework.http
def cors_enabled_function(request):
    # For more information about CORS and CORS preflight requests, see:
    # https://developer.mozilla.org/en-US/docs/Glossary/Preflight_request

    # Set CORS headers for the preflight request
    if request.method == "OPTIONS":
        # Allows GET requests from any origin with the Content-Type
        # header and caches preflight response for an 3600s
        headers = {
            "Access-Control-Allow-Origin": "*",
            "Access-Control-Allow-Methods": "GET",
            "Access-Control-Allow-Headers": "Content-Type",
            "Access-Control-Max-Age": "3600",
        }

        return ("", 204, headers)

    # Set CORS headers for the main request
    headers = {"Access-Control-Allow-Origin": "*"}

    return ("Hello World!", 200, headers)

Ir


// Package http provides a set of HTTP Cloud Functions samples.
package http

import (
	"fmt"
	"net/http"

	"github.com/GoogleCloudPlatform/functions-framework-go/functions"
)

// CORSEnabledFunction is an example of setting CORS headers.
// For more information about CORS and CORS preflight requests, see
// https://developer.mozilla.org/en-US/docs/Glossary/Preflight_request.
func CORSEnabledFunction(w http.ResponseWriter, r *http.Request) {
	// Set CORS headers for the preflight request
	if r.Method == http.MethodOptions {
		w.Header().Set("Access-Control-Allow-Origin", "*")
		w.Header().Set("Access-Control-Allow-Methods", "POST")
		w.Header().Set("Access-Control-Allow-Headers", "Content-Type")
		w.Header().Set("Access-Control-Max-Age", "3600")
		w.WriteHeader(http.StatusNoContent)
		return
	}
	// Set CORS headers for the main request.
	w.Header().Set("Access-Control-Allow-Origin", "*")
	fmt.Fprint(w, "Hello, World!")
}

func init() {
	functions.HTTP("CORSEnabledFunction", CORSEnabledFunction)
}

Java


import com.google.cloud.functions.HttpFunction;
import com.google.cloud.functions.HttpRequest;
import com.google.cloud.functions.HttpResponse;
import java.io.BufferedWriter;
import java.io.IOException;
import java.net.HttpURLConnection;

public class CorsEnabled implements HttpFunction {
  // corsEnabled is an example of setting CORS headers.
  // For more information about CORS and CORS preflight requests, see
  // https://developer.mozilla.org/en-US/docs/Glossary/Preflight_request.
  @Override
  public void service(HttpRequest request, HttpResponse response)
      throws IOException {
    // Set CORS headers
    //   Allows GETs from any origin with the Content-Type
    //   header and caches preflight response for 3600s
    response.appendHeader("Access-Control-Allow-Origin", "*");

    if ("OPTIONS".equals(request.getMethod())) {
      response.appendHeader("Access-Control-Allow-Methods", "GET");
      response.appendHeader("Access-Control-Allow-Headers", "Content-Type");
      response.appendHeader("Access-Control-Max-Age", "3600");
      response.setStatusCode(HttpURLConnection.HTTP_NO_CONTENT);
      return;
    }

    // Handle the main request.
    BufferedWriter writer = response.getWriter();
    writer.write("CORS headers set successfully!");
  }
}

.NET

using Google.Cloud.Functions.Framework;
using Microsoft.AspNetCore.Http;
using System.Net;
using System.Threading.Tasks;

namespace Cors;

// For more information about CORS and CORS preflight requests, see
// https://developer.mozilla.org/en-US/docs/Glossary/Preflight_request.
public class Function : IHttpFunction
{
    public async Task HandleAsync(HttpContext context)
    {
        HttpRequest request = context.Request;
        HttpResponse response = context.Response;

        // Set CORS headers
        //   Allows GETs from any origin with the Content-Type
        //   header and caches preflight response for 3600s

        response.Headers.Append("Access-Control-Allow-Origin", "*");
        if (HttpMethods.IsOptions(request.Method))
        {
            response.Headers.Append("Access-Control-Allow-Methods", "GET");
            response.Headers.Append("Access-Control-Allow-Headers", "Content-Type");
            response.Headers.Append("Access-Control-Max-Age", "3600");
            response.StatusCode = (int) HttpStatusCode.NoContent;
            return;
        }

        await response.WriteAsync("CORS headers set successfully!", context.RequestAborted);
    }
}

Ruby

FunctionsFramework.http "cors_enabled_function" do |request|
  # For more information about CORS and CORS preflight requests, see
  # https://developer.mozilla.org/en-US/docs/Glossary/Preflight_request
  # for more information.

  # Set CORS headers for the preflight request
  if request.options?
    # Allows GET requests from any origin with the Content-Type
    # header and caches preflight response for an 3600s
    headers = {
      "Access-Control-Allow-Origin"  => "*",
      "Access-Control-Allow-Methods" => "GET",
      "Access-Control-Allow-Headers" => "Content-Type",
      "Access-Control-Max-Age"       => "3600"
    }
    [204, headers, []]
  else
    # Set CORS headers for the main request
    headers = {
      "Access-Control-Allow-Origin" => "*"
    }

    [200, headers, ["Hello World!"]]
  end
end

PHP


use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use GuzzleHttp\Psr7\Response;

function corsEnabledFunction(ServerRequestInterface $request): ResponseInterface
{
    // Set CORS headers for preflight requests
    // Allows GETs from any origin with the Content-Type header
    // and caches preflight response for 3600s
    $headers = ['Access-Control-Allow-Origin' => '*'];

    if ($request->getMethod() === 'OPTIONS') {
        // Send response to OPTIONS requests
        $headers = array_merge($headers, [
            'Access-Control-Allow-Methods' => 'GET',
            'Access-Control-Allow-Headers' => 'Content-Type',
            'Access-Control-Max-Age' => '3600'
        ]);
        return new Response(204, $headers, '');
    } else {
        return new Response(200, $headers, 'Hello World!');
    }
}

Se o CORS não estiver configurado corretamente, pode ver erros como os seguintes:

XMLHttpRequest cannot load https://YOUR_FUNCTION_URL.
No 'Access-Control-Allow-Origin' header is present on the requested resource.
Origin 'https://YOUR_DOMAIN' is therefore not allowed access.

Limitações de CORS

Para pedidos de origem cruzada pré-enviados, os pedidos OPTIONS pré-enviados são enviados sem um cabeçalho de autorização, pelo que são rejeitados em todas as funções HTTP que requerem autenticação. Uma vez que os pedidos de pré-voo falham, os pedidos principais também falham. Para contornar esta limitação, use uma das seguintes opções:

Escreva funções orientadas por eventos

Escreva uma função orientada por eventos quando quiser que uma função seja acionada diretamente em resposta a eventos no seu Google Cloud projeto, como mensagens num tópico do Pub/Sub ou alterações num contentor do Cloud Storage.

As funções orientadas por eventos baseiam-se em CloudEvents, uma especificação padrão da indústria para descrever dados de eventos de forma comum. Pode saber mais sobre a especificação CloudEvents no repositório do GitHub do CloudEvents. O projeto CloudEvents também fornece um conjunto de SDKs CloudEvents para ajudar a trabalhar com objetos CloudEvents no seu código.

O exemplo seguinte mostra um ficheiro de origem de função acionada por eventos para cada tempo de execução. Consulte a estrutura do diretório de origem para ver informações sobre onde encontrar o código-fonte.

Node.js

Módulo ES

  import { cloudEvent } from "@google-cloud/functions-framework";
  cloudEvent('myCloudEventFunction', cloudEvent => {
    // Your code here
    // Access the CloudEvent data payload using cloudEvent.data
  });

Adicione as seguintes dependências, incluindo "type": "module" no ficheiro package.json:

  {
    "dependencies": {
      "@google-cloud/functions-framework": "^3.0.0"
    },
    "type": "module"
  }

Módulo CommonJS

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

// Register a CloudEvent function with the Functions Framework
functions.cloudEvent('myCloudEventFunction', cloudEvent => {
  // Your code here
  // Access the CloudEvent data payload using cloudEvent.data
});

Adicione as seguintes dependências ao ficheiro package.json:

  {
    "dependencies": {
      "@google-cloud/functions-framework": "^3.0.0"
    }
  }

No Node.js, regista uma função de controlador de CloudEvent com o Functions Framework para Node.js. A função do controlador tem de aceitar um objeto CloudEvent como argumento.

O ponto de entrada da função é o nome com o qual o controlador está registado no Functions Framework. Neste exemplo, o ponto de entrada é myCloudEventFunction.

Python

import functions_framework

# Register a CloudEvent function with the Functions Framework
@functions_framework.cloud_event
def my_cloudevent_function(cloud_event):
  # Your code here
  # Access the CloudEvent data payload via cloud_event.data

Em Python, regista uma função de controlador de CloudEvent com o Functions Framework para Python. A função do controlador tem de aceitar um objeto CloudEvent como argumento.

O ponto de entrada da função é o nome da função de controlador registada no Functions Framework. Neste exemplo, o ponto de entrada é my_cloudevent_function.

Ir

package mycloudeventfunction

import (
    "context"

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

func init() {
    // Register a CloudEvent function with the Functions Framework
    functions.CloudEvent("MyCloudEventFunction", myCloudEventFunction)
}

// Function myCloudEventFunction accepts and handles a CloudEvent object
func myCloudEventFunction(ctx context.Context, e event.Event) error {
    // Your code here
    // Access the CloudEvent data payload using e.Data() or e.DataAs(...)

    // Returning an error causes its message to be logged.
    // Example:
    err := myInternalFunction() // may return an error
    if err != nil {
        // Append error message to log
        return err
    }

    // Return nil if no error occurred
    return nil
}

Em Go, regista uma função de controlador CloudEvent com o Functions Framework para Go. A função de controlador tem de aceitar um objeto event.Event CloudEvents como argumento.

O ponto de entrada da função é o nome com o qual o controlador está registado no Functions Framework. Neste exemplo, o ponto de entrada é MyCloudEventFunction.

Java

package mycloudeventfunction;

import com.google.cloud.functions.CloudEventsFunction;
import io.cloudevents.CloudEvent;

// Define a class that implements the CloudEventsFunction interface
public class MyCloudEventFunction implements CloudEventsFunction {
  // Implement the accept() method to handle CloudEvents
  @Override
  public void accept(CloudEvent event) {
    // Your code here
    // Access the CloudEvent data payload using event.getData()
    // To get the data payload as a JSON string, use:
    // new String(event.getData().toBytes())
  }
}

Em Java, usa a API Java do Functions Framework para implementar uma classe de controlador CloudEvent com a interface CloudEventsFunction. O método accept() tem de aceitar um objeto CloudEvent como argumento e realizar qualquer processamento no evento.

O ponto de entrada da função é o nome totalmente qualificado da classe do controlador CloudEvent, incluindo o nome do pacote. Neste exemplo, o ponto de entrada é mycloudeventfunction.MyCloudEventFunction.

.NET

using CloudNative.CloudEvents;
using Google.Cloud.Functions.Framework;
using System.Threading;
using System.Threading.Tasks;

namespace MyProject
{
  // Define a class that implements the ICloudEventFunction<T> interface
  public class MyCloudEventFunction : ICloudEventFunction<CloudEventDataType>
  {
      // Implement the HandleAsync() method to handle CloudEvents
      public Task HandleAsync(CloudEvent cloudEvent, CloudEventDataType data, CancellationToken cancellationToken)
      {
          // Your code here
          // The data argument represents the CloudEvent data payload

          // Signal function completion
          return Task.CompletedTask;
      }
  }
}

Nos runtimes .NET, usa o Functions Framework para .NET para implementar uma classe de controlador CloudEvent com a interface ICloudEventFunction<T>. O método HandleAsync() aceita um objeto CloudEvent e a carga útil de dados CloudEvent associada como argumentos.

O tipo do argumento de payload de dados CloudEvent, apresentado no exemplo de código como CloudEventDataType, tem de corresponder ao tipo de evento que a função processa. A biblioteca .NET Google CloudEvents fornece tipos de dados para os vários eventos suportados pela Google.

O ponto de entrada da função é o nome totalmente qualificado da classe do controlador de CloudEvent, incluindo o espaço de nomes. Neste exemplo, o ponto de entrada é MyProject.MyCloudEventFunction.

Ruby

require "functions_framework"

# Register a CloudEvent function with the Functions Framework
FunctionsFramework.cloud_event "my_cloudevent_function" do |cloud_event|
  # Your code here
  # Access the CloudEvent data payload via cloud_event.data
end

Em Ruby, regista uma função de controlador de CloudEvent com o Functions Framework para Ruby. A função de controlador tem de aceitar um objeto CloudEvents Event como argumento.

O ponto de entrada da função é o nome com o qual o controlador está registado no Functions Framework. Neste exemplo, o ponto de entrada é my_cloudevent_function.

PHP

<?php

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

// Register a CloudEvent function with the Functions Framework
FunctionsFramework::cloudEvent('myCloudEventFunction', 'myCloudEventHandler');

// Define your CloudEvent handler
function myCloudEventHandler(CloudEventInterface $event): void
{
    // Your code here
    // Access the CloudEvent data payload using $event->getData()
}

Em PHP, regista uma função de controlador de CloudEvent com o Functions Framework para PHP. A função de controlador tem de aceitar um argumento em conformidade com a interface CloudEventInterface.

O ponto de entrada da função é o nome com o qual o controlador está registado no Functions Framework. Neste exemplo, o ponto de entrada é myCloudEventFunction.

Para funções acionadas por eventos, os dados de eventos são transmitidos à sua função no formato CloudEvents, com uma carga útil de dados CloudEvent correspondente ao tipo de evento que aciona a sua função. Consulte os acionadores de funções para ver informações sobre os acionadores suportados, os tipos de eventos e os formatos de dados de eventos associados.

O repositório Google Events contém recursos para trabalhar com CloudEvents emitidos pela Google.

Terminação da função

O Cloud Run considera a execução da função baseada em eventos concluída quando a função devolve um valor. Se a função criar tarefas em segundo plano (como com threads, futuros, objetos JavaScript Promise, callbacks ou processos do sistema), tem de terminar ou resolver estas tarefas antes de regressar da função. As tarefas não terminadas antes do retorno da função podem não ser concluídas e podem causar um comportamento indefinido.

Novas tentativas automáticas

As funções acionadas por eventos podem ser configuradas para repetir automaticamente as invocações com falhas. Consulte o artigo Voltar a tentar funções acionadas por eventos para mais informações.

O que se segue?