Escribe funciones de HTTP
En Cloud Run Functions, debes usar funciones de HTTP para invocar una función a través de una solicitud HTTP(S). Para permitir la semántica de HTTP, las firmas de las funciones de HTTP aceptan argumentos específicos de HTTP.
Implementación
En el ejemplo siguiente, se muestra el archivo fuente de una función básica HTTP para cada entorno de ejecución. Consulta la Estructura del directorio del código fuente para obtener información sobre dónde debe ubicarse el código fuente.
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');
});
En Node.js, registra una función de controlador HTTP con Functions Framework para Node.js. Tu función de controlador HTTP debe ser una función de middleware express que acepte los argumentos de solicitud y respuesta y que envíe una respuesta HTTP.
Cloud Run Functions analiza automáticamente el cuerpo de la solicitud según el
encabezado Content-Type de la solicitud con
body-parser,
de modo que tú puedas acceder a los objetos req.body y req.rawBody en tu controlador HTTP.
El
punto de entrada de la función es el nombre con el que se registra el controlador en Functions Framework.
En este ejemplo, el punto de entrada es 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'
En Python, las funciones de controlador HTTP se registran con Functions Framework para Python. Estas funciones deben aceptar un objeto de solicitud de Flask como un argumento y devolver un valor que Flask pueda convertir en un objeto de respuesta HTTP.
El
punto de entrada de la función
es el nombre de la función del controlador registrada en Functions Framework.
En este ejemplo, el punto de entrada es 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")
}
En Go, las funciones de controlador HTTP se registran con
Functions Framework para Go
en la función init(). Estas funciones deben usar la
interfaz http.HandlerFunc
estándar para enviar una respuesta HTTP.
El
punto de entrada de la función es el nombre con el que se registra el controlador en Functions Framework.
En este ejemplo, el punto de entrada es MyHTTPFunction.
La función de controlador HTTP debe implementar la
interfaz http.HandlerFunc
estándar. Esta acepta una interfaz http.ResponseWriter que la función usa para
crear una respuesta a la solicitud, así como un puntero a un struct http.Request que contiene los detalles de la
solicitud HTTP entrante.
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");
}
}
En Java, debes usar la
API de Functions Framework para Java
con el objetivo de implementar una clase de controlador HTTP con la
interfaz HttpFunction. El método service() debe enviar una respuesta HTTP.
El
punto de entrada de la función
es el nombre completamente calificado de la clase del controlador HTTP, incluido el nombre
del paquete. En este ejemplo, el punto de entrada es myhttpfunction.MyHttpFunction.
Tu método service recibe un objeto
HttpRequest que describe la solicitud HTTP entrante, así como un objeto HttpResponse
que se propaga en tu función con un mensaje de respuesta.
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");
}
}
}
En los entornos de ejecución de .NET, debes usar
Functions Framework para .NET
para implementar una clase de controlador HTTP con la
interfaz IHttpFunction. El método HandleAsync() acepta un objeto HttpContext
estándar de ASP.NET como argumento y debe enviar una respuesta HTTP.
El
punto de entrada de la función es el nombre completamente calificado de la clase de controlador HTTP, incluido el espacio de nombres.
En este ejemplo, el punto de entrada es 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
En Ruby, debes registrar las funciones de controlador HTTP con Functions Framework para Ruby. Estas funciones deben aceptar un objeto de solicitud de Rack como argumento y devolver un valor que se pueda usar como una respuesta HTTP.
El
punto de entrada de la función es el nombre con el que se registra el controlador en Functions Framework.
En este ejemplo, el punto de entrada es 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';
}
En PHP, debes registrar las funciones de controlador HTTP con
Functions Framework para PHP.
Estas funciones deben aceptar un argumento que implemente la interfaz
ServerRequestInterface de PSR-7
y debe devolver una respuesta HTTP como una cadena o un objeto que
implementa la interfaz ResponseInterface
de PSR-7.
El
punto de entrada de la función es el nombre con el que se registra el controlador en Functions Framework.
En este ejemplo, el punto de entrada es myHttpFunction.
Solicitudes y respuestas HTTP
Las funciones de HTTP aceptan los métodos de solicitud HTTP enumerados en la página activadores HTTP. El controlador HTTP puede inspeccionar el método de solicitud y llevar a cabo diferentes acciones en función del método.
La función debe enviar una respuesta HTTP. Si la función crea tareas
en segundo plano (como subprocesos, futuros, objetos Promise de JavaScript, devoluciones de
llamadas o procesos del sistema), debes finalizar estas tareas o, de lo contrario, resolverlas antes de enviar una respuesta HTTP. Es posible que no se completen todas las tareas que no se finalicen
antes de enviar la respuesta HTTP, lo que puede causar un comportamiento indefinido.
Consulta Activadores HTTP para obtener más información sobre las funciones de HTTP y las opciones asociadas.
Administra CORS
El uso compartido de recursos entre dominios (CORS) es una forma de permitir que las aplicaciones que se ejecutan en un dominio accedan a los recursos de otro dominio. Por ejemplo, es posible que debas permitir que el dominio haga solicitudes al dominio de Cloud Run Functions para acceder a la función.
Si CORS no se configura de forma correcta, es posible que se generen errores como el siguiente:
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.
Para permitir que la función reciba solicitudes de origen cruzado, configura el
encabezado Access-Control-Allow-Origin
según corresponda en la respuesta HTTP. Para las
solicitudes de origen cruzado con solicitud preliminar, debes responder a la solicitud preliminar OPTIONS con un código de respuesta
204 y encabezados adicionales.
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!'); } }
Limitaciones de CORS
Para las solicitudes preliminares de origen cruzado, las solicitudes preliminares OPTIONS se envían
sin un encabezado Authorization, por lo que se rechazarán en todas las funciones
HTTP que requieran autenticación. Como las solicitudes preliminares fallan,
la solicitud principal también lo hará. Para evitar esta limitación, usa una de
las opciones siguientes:
- Permite las invocaciones no autenticadas de tu función.
- Aloja la aplicación web y las funciones de Cloud Run en el mismo dominio para evitar el CORS. Para ello, integra Firebase Hosting en Cloud Run Functions.
Próximos pasos
- Obtén más información sobre los activadores HTTP.
- Aprende a implementar una función de Cloud Run.