Scrivi funzioni HTTP
In Cloud Run Functions, utilizzi le funzioni HTTP quando vuoi richiamare una funzione tramite una richiesta HTTP(S). Per consentire la semantica HTTP, le firme delle funzioni HTTP accettano argomenti specifici di HTTP.
Implementazione
L'esempio seguente mostra un file di codice sorgente di una funzione HTTP di base per ogni runtime. Consulta Struttura della directory di origine per informazioni su dove trovare il codice sorgente.
Node.js
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');
});
In Node.js, registri una funzione gestore HTTP con il framework di Functions per Node.js. La funzione gestore HTTP deve essere una funzione middleware Express che accetta gli argomenti request e response e invia una risposta HTTP.
Cloud Run Functions analizza automaticamente il corpo della richiesta in base all'intestazione Content-Type della richiesta utilizzando body-parser, permettendoti di accedere agli oggetti req.body e req.rawBody nel gestore HTTP.
L'entry point della funzione è il nome con cui il gestore viene registrato con il framework di Functions.
In questo esempio, l'entry point è 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 gestore HTTP con il framework di Functions per Python. La funzione gestore HTTP deve accettare un oggetto richiesta Flask come argomento e restituire un valore che Flask può convertire in un oggetto risposta HTTP.
L'entry point della funzione è il nome della funzione gestore registrata con il framework di Functions.
In questo esempio, l'entry point è my_http_function.
Go
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 gestore HTTP con il framework di Functions per Go nella funzione init(). La funzione gestore HTTP deve utilizzare l'interfaccia http.HandlerFunc standard per inviare una risposta HTTP.
L'entry point della funzione è il nome con cui il gestore viene registrato con il framework di Functions.
In questo esempio, l'entry point è MyHTTPFunction.
La funzione gestore HTTP deve implementare l'interfaccia http.HandlerFunc standard. Accetta un'interfaccia http.ResponseWriter, utilizzata dalla funzione per creare una risposta alla richiesta, e un puntatore a uno 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 gestore HTTP con l'interfaccia HttpFunction. Il metodo service() deve inviare una risposta HTTP.
L'entry point della funzione è il nome completo della classe gestore HTTP, incluso il nome del pacchetto. In questo esempio, l'entry point è myhttpfunction.MyHttpFunction.
Il metodo service riceve un oggetto HttpRequest che descrive la richiesta HTTP in entrata e un oggetto HttpResponse, compilato dalla funzione con un messaggio di risposta.
C#
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 gestore HTTP con l'interfaccia IHttpFunction. Il metodo HandleAsync() accetta un oggetto HttpContext ASP.NET standard come argomento e deve inviare una risposta HTTP.
L'entry point della funzione è il nome completo della classe gestore HTTP, incluso lo spazio dei nomi.
In questo esempio, l'entry point è 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 gestore HTTP con il framework di Functions per Ruby. La funzione gestore HTTP deve accettare un oggetto richiesta Rack come argomento e restituire un valore che può essere utilizzato come risposta HTTP.
L'entry point della funzione è il nome con cui il gestore viene registrato con il framework di Functions.
In questo esempio, l'entry point è 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 gestore HTTP con il framework di Functions per PHP.
La funzione 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.
L'entry point della funzione è il nome con cui il gestore viene registrato con il framework di Functions.
In questo esempio, l'entry point è myHttpFunction.
Richieste e risposte HTTP
Le funzioni HTTP accettano i metodi di richiesta HTTP elencati nella pagina Trigger HTTP. Il gestore HTTP può esaminare il metodo della richiesta ed eseguire azioni diverse in base al metodo.
La funzione deve inviare una risposta HTTP. Se la funzione crea attività in background (ad esempio con thread, future, oggetti JavaScript Promise, callback o processi di sistema), devi terminare o risolvere in altro modo queste attività prima di inviare una risposta HTTP. Le attività non terminate prima dell'invio della risposta HTTP potrebbero non essere completate e causare un comportamento non definito.
Per saperne di più sulle funzioni HTTP e sulle opzioni associate, consulta Trigger HTTP.
Gestione di CORS
La condivisione delle risorse tra origini (CORS) è un modo per consentire 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 inviare richieste al dominio Cloud Run Functions per accedere alla tua funzione.
Se la configurazione di CORS non è corretta, 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.
Per consentire richieste multiorigine alla tua funzione, imposta l'intestazione
Access-Control-Allow-Origin in base alle esigenze nella risposta HTTP. Per le richieste multiorigine con preflight, devi rispondere alla richiesta preflight OPTIONS con un codice di risposta 204 e intestazioni aggiuntive.
Node.js
Python
Go
Java
C#
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
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!'); } }
Limitazioni della CORS
Per le richieste multiorigine con preflight, vengono inviate richieste preflight OPTIONS senza un'intestazione Authorization, che verranno quindi rifiutate da tutte le funzioni HTTP che richiedono l'autenticazione. Poiché le richieste preflight non riescono, anche le richieste principali non riusciranno. Per ovviare a questo limite, utilizza una delle seguenti opzioni:
- Consenti chiamate non autenticate della tua funzione.
- Ospita la tua app web e le funzioni Cloud Run sullo stesso dominio per evitare la CORS. Per farlo, puoi integrare Firebase Hosting con Cloud Run Functions.
Passaggi successivi
- Scopri di più sui trigger HTTP.
- Scopri come eseguire il deployment di una funzione Cloud Run.