Scrivi funzioni Cloud Run

Questa pagina descrive come scrivere funzioni Cloud Run basate su HTTP e sugli eventi con Functions Framework.

Panoramica del framework di Functions

Quando scrivi il codice sorgente delle funzioni, devi utilizzare Functions Framework, una libreria open source per scrivere funzioni Cloud Run. Con Functions Framework, puoi scrivere funzioni leggere che vengono eseguite in Cloud Run e in altri ambienti, tra cui la tua macchina di sviluppo locale e gli ambienti basati su Knative.

Functions Framework ti consente di:

  • Richiama una funzione Cloud Run in risposta a una richiesta.
  • Esegue automaticamente l'unmarshalling degli eventi conformi alla specifica CloudEvents, una specifica standard del settore per descrivere i dati degli eventi in modo comune.
  • Avvia un server di sviluppo locale per i test.

Functions Framework fornisce un'interfaccia per la creazione di servizi modulari. Per utilizzare Functions Framework nel codice sorgente, specifica quanto segue:

Entry point della funzione

Il codice sorgente deve definire un punto di ingresso della funzione, ovvero il codice che viene eseguito quando Cloud Run richiama la funzione. Specifichi questo entry point quando esegui il deployment della funzione.

Il modo in cui definisci il punto di ingresso dipende dal runtime del linguaggio che utilizzi. Alcuni linguaggi utilizzano una funzione come punto di ingresso, mentre altri utilizzano una classe.

Tipo di firma

Quando scrivi il codice sorgente di una funzione con Functions Framework, devi specificare uno dei due tipi di firma:

  • Funzioni HTTP: registra una funzione di gestione HTTP. Utilizza una funzione HTTP quando la tua funzione ha bisogno di un endpoint URL e deve rispondere alle richieste HTTP, ad esempio per i webhook.
  • Funzioni basate su eventi, note anche come funzioni CloudEvents: registra una funzione di gestione CloudEvents. Utilizza una funzione basata su eventi quando la funzione viene attivata direttamente in risposta a eventi all'interno del tuo progetto Google Cloud , ad esempio messaggi in un argomento Pub/Sub o modifiche in un bucket Cloud Storage.

Struttura della directory di origine

Functions Framework è supportato in numerosi linguaggi di programmazione. Il runtime del linguaggio che scegli e il tipo di funzione che vuoi scrivere determinano la struttura del codice e l'implementazione della funzione.

Affinché Cloud Run possa individuare la definizione della funzione, ogni runtime del linguaggio ha requisiti per la strutturazione del codice sorgente.

Node.js

La struttura di base delle directory per le funzioni Node.js è la seguente:

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

Per impostazione predefinita, Cloud Run tenta di caricare il codice sorgente da un file denominato index.js nella directory principale della funzione. Per specificare un file di origine principale diverso, utilizza il campo main nel file package.json.

Il file package.json deve includere anche Functions Framework per Node.js come dipendenza:

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

Il codice nel file principale deve definire l'entry point della funzione e può importare altro codice e moduli Node.js. Il file principale può anche definire più entry point di funzione che possono essere implementati separatamente.

Per saperne di più, consulta la panoramica del runtime Node.js e il framework Functions per Node.js.

Python

La struttura di base delle directory per le funzioni Python è la seguente:

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

Cloud Run carica il codice sorgente da un file denominato main.py nella directory principale della funzione. Devi assegnare al file principale il nome main.py.

Il file requirements.txt deve includere Functions Framework per Python come dipendenza:

functions-framework==3.*

Il codice nel file main.py deve definire il punto di ingresso della funzione e può importare altro codice e dipendenze esterne come di consueto. Il file main.py può anche definire più punti di ingresso della funzione che possono essere implementati separatamente.

Per saperne di più, consulta la panoramica del runtime Python e il Functions Framework per Python.

Vai

La struttura di base delle directory per le funzioni Go è la seguente:

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

La funzione deve trovarsi in un pacchetto Go nella directory principale del progetto. Il pacchetto e i relativi file di origine possono avere qualsiasi nome, tranne che la funzione non può trovarsi in package main. Se hai bisogno di un pacchetto main, ad esempio per i test locali, puoi crearne uno in una sottodirectory:

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

Il file go.mod deve includere Functions Framework per Go come dipendenza:

module example.com/my-module

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

Il codice nel pacchetto radice deve definire il punto di ingresso della funzione e può importare altro codice da sottopacchetti e dipendenze come di consueto. Il pacchetto può anche definire più punti di ingresso della funzione che possono essere implementati separatamente.

Per saperne di più, consulta la panoramica del runtime Go e il framework Functions per Go.

Java

La struttura di base delle directory per le funzioni Java è la seguente:

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

I file di origine Java devono trovarsi nella directory src/main/java/ e possono avere qualsiasi nome. Se i file di origine dichiarano un pacchetto, aggiungi una directory aggiuntiva in src/main/java con il nome del pacchetto:

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

Ti consigliamo di inserire i test associati in una sottodirectory src/test/java/.

Il file pom.xml deve includere Functions Framework per Java come dipendenza:

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

Il codice nei file sorgente deve definire il punto di ingresso della funzione e può importare altro codice e dipendenze esterne come di consueto. I file di origine possono anche definire più punti di ingresso della funzione che possono essere implementati separatamente.

Per saperne di più, consulta la panoramica del runtime Java e il framework Functions per Java.

.NET

La struttura di base delle directory per le funzioni .NET è la seguente:

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

Puoi strutturare i tuoi progetti come faresti con qualsiasi altro codice sorgente .NET. I file di origine possono avere qualsiasi nome.

Il file di progetto deve includere Functions Framework per .NET come dipendenza:

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

Il codice nei file sorgente deve definire il punto di ingresso della funzione e può importare altro codice e dipendenze esterne come di consueto. I file di origine possono anche definire più punti di ingresso della funzione che possono essere implementati separatamente.

Per saperne di più, consulta la panoramica del runtime.NET e il framework Functions per .NET.

Ruby

La struttura di base delle directory per le funzioni Ruby è la seguente:

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

Cloud Run carica il codice sorgente da un file denominato app.rb nella directory principale della funzione. Il file principale deve essere denominato app.rb.

Il file Gemfile deve includere Functions Framework per Ruby come dipendenza:

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

Il codice nel file app.rb deve definire il punto di ingresso della funzione e può importare altro codice e dipendenze esterne come di consueto. Il file app.rb può anche definire più punti di ingresso della funzione che possono essere implementati separatamente.

Per saperne di più, consulta la panoramica del runtime Ruby e il framework Functions per Ruby.

PHP

La struttura di base delle directory per le funzioni PHP è la seguente:

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

Cloud Run carica il codice sorgente da un file denominato index.php nella directory principale della funzione. Devi assegnare al file principale il nome index.php.

Il file composer.json deve includere Functions Framework per PHP come dipendenza:

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

Il codice nel file index.php deve definire il punto di ingresso della funzione e può importare altro codice e dipendenze esterne come di consueto. Il file index.php può anche definire più punti di ingresso della funzione che possono essere implementati separatamente.

Per saperne di più, consulta la panoramica del runtime PHP e il framework Functions per PHP.

Se raggruppi più funzioni in un unico progetto, tieni presente che ogni funzione potrebbe finire per condividere lo stesso insieme di dipendenze. Tuttavia, alcune delle funzioni potrebbero non richiedere tutte le dipendenze.

Ove possibile, consigliamo di suddividere i codebase multifunzione di grandi dimensioni e di inserire ogni funzione nella propria directory di primo livello, come mostrato negli esempi precedenti, con i propri file di configurazione del progetto e di origine. Questo approccio riduce al minimo il numero di dipendenze richieste per una determinata funzione, il che a sua volta riduce la quantità di memoria necessaria per la funzione.

Scrivere funzioni HTTP

Scrivi una funzione HTTP quando vuoi richiamare una funzione tramite una richiesta HTTP(S). Per consentire la semantica HTTP, utilizza Function Framework e specifica la firma della funzione HTTP per accettare argomenti specifici di HTTP.

L'esempio seguente mostra un file di origine della funzione HTTP di base per ogni runtime. Per un esempio di funzionamento completo, consulta Esegui il deployment di una funzione Cloud Run utilizzando Google Cloud CLI. Per maggiori informazioni su dove trovare il codice sorgente, consulta Struttura della directory di origine.

Node.js

Modulo ES

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

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

Aggiungi le seguenti dipendenze, incluso "type": "module", al tuo file package.json:

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

Modulo 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');
  });

Aggiungi le seguenti dipendenze nel file package.json:

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

In Node.js, registri una funzione di gestione HTTP con il Framework di Functions per Node.js. La funzione del gestore HTTP deve essere una funzione middleware Express che accetta gli argomenti richiesta e risposta e invia una risposta HTTP.

Cloud Run analizza automaticamente il corpo della richiesta in base all'intestazione Content-Type della richiesta utilizzando body-parser, in modo da poter accedere agli oggetti req.body e req.rawBody nel gestore HTTP.

Il punto di ingresso della funzione è il nome con cui il gestore viene registrato con Functions Framework. In questo esempio, il punto di ingresso è 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'

In Python, registri una funzione di gestione HTTP con il Framework di Functions per Python. La funzione del gestore HTTP deve accettare un oggetto richiesta Flask come argomento e restituire un valore che Flask può convertire in un oggetto risposta HTTP.

Il punto di ingresso della funzione è il nome con cui il gestore viene registrato con Functions Framework. In questo esempio, il punto di ingresso è my_http_function.

Vai

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")
}

In Go, registri una funzione di gestione HTTP con il Framework di Functions per Go nella funzione init(). La funzione del gestore HTTP deve utilizzare l'interfaccia standard http.HandlerFunc per inviare una risposta HTTP.

Il punto di ingresso della funzione è il nome con cui il gestore viene registrato con Functions Framework. In questo esempio, il punto di ingresso è MyHTTPFunction.

La funzione del gestore HTTP deve implementare l'interfaccia standard http.HandlerFunc. Accetta un'interfaccia http.ResponseWriter che la funzione utilizza per creare una risposta alla richiesta e un puntatore a una struct http.Request contenente i dettagli della richiesta HTTP in entrata.

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");
  }
}

In Java, utilizzi l'API Functions Framework Java per implementare una classe di gestione HTTP con l'interfaccia HttpFunction. Il metodo service() deve inviare una risposta HTTP.

Il punto di ingresso della funzione è il nome completo della classe del gestore HTTP, incluso il nome del pacchetto. In questo esempio, il punto di ingresso è myhttpfunction.MyHttpFunction.

Il metodo service riceve un oggetto HttpRequest che descrive la richiesta HTTP in entrata e un oggetto HttpResponse che la funzione compila con un messaggio di risposta.

.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");
        }
    }
}

Nei runtime .NET, utilizzi il Framework di Functions per .NET per implementare una classe di gestore HTTP con l'interfaccia IHttpFunction. Il metodo HandleAsync() accetta un oggetto HttpContext ASP.NET standard come argomento e deve inviare una risposta HTTP.

Il punto di ingresso della funzione è il nome completo della classe del gestore HTTP, incluso lo spazio dei nomi. In questo esempio, il punto di ingresso è 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

In Ruby, registri una funzione di gestione HTTP con il Framework di Functions per Ruby. La funzione del gestore HTTP deve accettare un oggetto richiesta Rack come argomento e restituire un valore che può essere utilizzato come risposta HTTP.

Il punto di ingresso della funzione è il nome con cui il gestore viene registrato con Functions Framework. In questo esempio, il punto di ingresso è 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';
}

In PHP, registri una funzione di gestione HTTP con il Framework di Functions per PHP. La funzione del gestore HTTP deve accettare un argomento che implementa l'interfaccia PSR-7 ServerRequestInterface e deve restituire una risposta HTTP come stringa o oggetto che implementa l'interfaccia PSR-7 ResponseInterface.

Il punto di ingresso della funzione è il nome con cui il gestore viene registrato con Functions Framework. In questo esempio, il punto di ingresso è myHttpFunction.

Richieste e risposte HTTP

Quando registri una funzione di gestione HTTP con Functions Framework, il gestore HTTP può esaminare il metodo della richiesta ed eseguire azioni diverse in base al metodo.

Quando configuri un provider di eventi per inviare richieste HTTP alla tua funzione Cloud Run, la funzione invia una risposta HTTP. Se la funzione crea attività in background (ad esempio con thread, future, oggetti Promise JavaScript, callback o processi di sistema), devi terminare o risolvere queste attività prima di inviare una risposta HTTP. Le attività non terminate prima dell'invio della risposta HTTP potrebbero non essere completate e potrebbero causare un comportamento indefinito.

Gestire CORS

La condivisione delle risorse tra origini (CORS) consente alle applicazioni in esecuzione su un dominio di accedere alle risorse di un altro dominio. Ad esempio, potrebbe essere necessario consentire al tuo dominio di effettuare richieste al dominio delle funzioni Cloud Run per accedere alla tua funzione.

Per consentire le richieste multiorigine alla tua funzione, imposta l'intestazione Access-Control-Allow-Origin in modo appropriato nella risposta HTTP. Per le richieste tra origini preflight, devi rispondere alla richiesta preflight OPTIONS con un codice di risposta 204 e intestazioni aggiuntive.

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)

Go


// 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 CORS non è configurato correttamente, potresti visualizzare errori come i seguenti:

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.

Limitazioni CORS

Per le richieste multiorigine preflight, le richieste OPTIONS preflight vengono inviate senza un'intestazione Authorization, pertanto verranno rifiutate in tutte le funzioni HTTP che richiedono l'autenticazione. Poiché le richieste preflight non vanno a buon fine, anche le richieste principali non andranno a buon fine. Per ovviare a questo limite, utilizza una delle seguenti opzioni:

Scrivere funzioni basate su eventi

Scrivi una funzione basata su eventi quando vuoi che venga attivata direttamente in risposta a eventi all'interno del tuo progetto Google Cloud , ad esempio messaggi in un argomento Pub/Sub o modifiche in un bucket Cloud Storage.

Le funzioni basate su eventi si basano su CloudEvents, una specifica standard del settore per descrivere i dati degli eventi in modo comune. Puoi scoprire di più sulla specifica CloudEvents nel repository GitHub di CloudEvents. Il progetto CloudEvents fornisce anche un insieme di SDK CloudEvents per aiutarti a lavorare con gli oggetti CloudEvents nel tuo codice.

L'esempio seguente mostra un file di origine della funzione basata su eventi per ogni runtime. Consulta Struttura della directory di origine per informazioni su dove trovare il codice sorgente.

Node.js

Modulo ES

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

Aggiungi le seguenti dipendenze, incluso "type": "module", al tuo file package.json:

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

Modulo 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
});

Aggiungi le seguenti dipendenze nel file package.json:

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

In Node.js, registri una funzione di gestione CloudEvent con il Framework di Functions per Node.js. La funzione del gestore deve accettare un oggetto CloudEvent come argomento.

Il punto di ingresso della funzione è il nome con cui il gestore viene registrato con Functions Framework. In questo esempio, il punto di ingresso è 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

In Python, registri una funzione di gestione CloudEvent con il Framework di Functions per Python. La funzione del gestore deve accettare un oggetto CloudEvent come argomento.

L'entry point della funzione è il nome della funzione di gestione registrata con Functions Framework. In questo esempio, il punto di ingresso è my_cloudevent_function.

Vai

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
}

In Go, registri una funzione di gestione CloudEvent con il Framework di Functions per Go. La funzione di gestione deve accettare un oggetto CloudEvents event.Event come argomento.

Il punto di ingresso della funzione è il nome con cui il gestore viene registrato con Functions Framework. In questo esempio, il punto di ingresso è 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())
  }
}

In Java, utilizzi l'API Functions Framework Java per implementare una classe di gestione CloudEvent con l'interfaccia CloudEventsFunction. Il metodo accept() deve accettare un oggetto CloudEvent come argomento ed eseguire l'elaborazione dell'evento.

Il punto di ingresso della funzione è il nome completo della classe del gestore CloudEvent, incluso il nome del pacchetto. In questo esempio, il punto di ingresso è 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;
      }
  }
}

Nei runtime .NET, utilizzi il Functions Framework per .NET per implementare una classe di gestione CloudEvent con l'interfaccia ICloudEventFunction<T>. Il metodo HandleAsync() accetta un oggetto CloudEvent e il payload di dati CloudEvent associato come argomenti.

Il tipo di argomento del payload di dati CloudEvent, mostrato nel codice di esempio come CloudEventDataType, deve corrispondere al tipo di evento gestito dalla funzione. La libreria Google CloudEvents .NET fornisce tipi di dati per i vari eventi supportati da Google.

Il punto di ingresso della funzione è il nome completo della classe del gestore CloudEvent, incluso lo spazio dei nomi. In questo esempio, il punto di ingresso è 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

In Ruby, registri una funzione di gestione CloudEvent con il Framework di Functions per Ruby. La funzione del gestore deve accettare un oggetto CloudEvents Event come argomento.

Il punto di ingresso della funzione è il nome con cui il gestore viene registrato con Functions Framework. In questo esempio, il punto di ingresso è 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()
}

In PHP, registri una funzione di gestione di CloudEvent con il Framework di Functions per PHP. La funzione del gestore deve accettare un argomento conforme all'interfaccia CloudEventInterface.

Il punto di ingresso della funzione è il nome con cui il gestore viene registrato con Functions Framework. In questo esempio, il punto di ingresso è myCloudEventFunction.

Per le funzioni basate su eventi, i dati degli eventi vengono passati alla funzione nel formato CloudEvents, con un payload di dati CloudEvent corrispondente al tipo di evento che attiva la funzione. Consulta Trigger di funzione per informazioni su trigger, tipi di eventi e formati dei dati degli eventi associati supportati.

Il repository Google Events contiene risorse per l'utilizzo di CloudEvents emessi da Google.

Termine della funzione

Cloud Run considera completata l'esecuzione della funzione basata su eventi quando la funzione restituisce un valore. Se la funzione crea attività in background (ad esempio con thread, future, oggetti Promise JavaScript, callback o processi di sistema), devi terminare o risolvere in altro modo queste attività prima di restituire la funzione. Le attività non terminate prima che la funzione restituisca un valore potrebbero non essere completate e potrebbero causare un comportamento indefinito.

Nuovi tentativi automatici

Le funzioni basate su eventi possono essere configurate per riprovare automaticamente le invocazioni non riuscite. Per saperne di più, consulta Nuovo tentativo per le funzioni basate su eventi.

Passaggi successivi