Activadores HTTP

Puedes invocar Cloud Functions con una solicitud HTTP mediante los métodos HTTP POST, PUT, GET, DELETE y OPTIONS. A fin de crear un extremo HTTP para tu función, especifica --trigger-http como el tipo de activador cuando implementas la función. Desde el punto de vista del emisor, las invocaciones de HTTP son síncronas, lo que significa que el resultado de la ejecución de la función se mostrará en la respuesta a la solicitud HTTP.

Por ejemplo, con el siguiente comando de gcloud se implementa una función en el entorno de ejecución de Node.js 10 que se activará mediante solicitudes HTTP:

gcloud functions deploy FUNCTION_NAME --runtime nodejs10 --trigger-http --allow-unauthenticated

Las funciones de HTTP requieren autenticación de forma predeterminada. La marca --allow-unauthenticated te permite acceder a la función sin autenticación. Omítela para exigir autenticación.

Puedes usar la utilidad de línea de comandos de cURL disponible de forma común para invocar funciones de HTTP. El siguiente comando de cURL realiza una solicitud POST con algunos datos a la URL de una función de HTTP implementada:

curl -X POST "https://YOUR_REGION-YOUR_PROJECT_ID.cloudfunctions.net/FUNCTION_NAME" -H "Content-Type:application/json" --data '{"name":"Keyboard Cat"}'

donde:

  • YOUR_REGION es la región en la que se implementa tu función.
  • YOUR_PROJECT_ID es el ID del proyecto de Google Cloud Platform.
  • FUNCTION_NAME es el nombre de la función de HTTP que implementaste.

La URL activadora para una función de HTTP se puede ver después de implementar la función o se puede consultar en cualquier momento a través del comando de gcloud functions describe.

También puedes activar tus funciones de HTTP directamente a través de la herramienta de gcloud. El siguiente comando llama a una función y le envía algunos datos en el cuerpo de una solicitud HTTP POST:

gcloud functions call FUNCTION_NAME --data '{"name":"Keyboard Cat"}'

Muestra de código

Node.js

const escapeHtml = require('escape-html');

/**
 * HTTP Cloud Function.
 *
 * @param {Object} req Cloud Function request context.
 *                     More info: https://expressjs.com/en/api.html#req
 * @param {Object} res Cloud Function response context.
 *                     More info: https://expressjs.com/en/api.html#res
 */
exports.helloHttp = (req, res) => {
  res.send(`Hello ${escapeHtml(req.query.name || req.body.name || 'World')}!`);
};

Python

from flask import escape

def hello_http(request):
    """HTTP Cloud Function.
    Args:
        request (flask.Request): The request object.
        <https://flask.palletsprojects.com/en/1.1.x/api/#incoming-request-data>
    Returns:
        The response text, or any set of values that can be turned into a
        Response object using `make_response`
        <https://flask.palletsprojects.com/en/1.1.x/api/#flask.make_response>.
    """
    request_json = request.get_json(silent=True)
    request_args = request.args

    if request_json and 'name' in request_json:
        name = request_json['name']
    elif request_args and 'name' in request_args:
        name = request_args['name']
    else:
        name = 'World'
    return 'Hello {}!'.format(escape(name))

Go


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

import (
	"encoding/json"
	"fmt"
	"html"
	"net/http"
)

// HelloHTTP is an HTTP Cloud Function with a request parameter.
func HelloHTTP(w http.ResponseWriter, r *http.Request) {
	var d struct {
		Name string `json:"name"`
	}
	if err := json.NewDecoder(r.Body).Decode(&d); err != nil {
		fmt.Fprint(w, "Hello, World!")
		return
	}
	if d.Name == "" {
		fmt.Fprint(w, "Hello, World!")
		return
	}
	fmt.Fprintf(w, "Hello, %s!", html.EscapeString(d.Name))
}

Java


import com.google.cloud.functions.HttpFunction;
import com.google.cloud.functions.HttpRequest;
import com.google.cloud.functions.HttpResponse;
import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.logging.Logger;

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

  private static final Gson gson = new Gson();

  @Override
  public void service(HttpRequest request, HttpResponse response)
      throws IOException {
    // Check URL parameters for "name" field
    // "world" is the default value
    String name = request.getFirstQueryParameter("name").orElse("world");

    // Parse JSON request and check for "name" field
    try {
      JsonElement requestParsed = gson.fromJson(request.getReader(), JsonElement.class);
      JsonObject requestJson = null;

      if (requestParsed != null && requestParsed.isJsonObject()) {
        requestJson = requestParsed.getAsJsonObject();
      }

      if (requestJson != null && requestJson.has("name")) {
        name = requestJson.get("name").getAsString();
      }
    } catch (JsonParseException e) {
      logger.severe("Error parsing JSON: " + e.getMessage());
    }

    var writer = new PrintWriter(response.getWriter());
    writer.printf("Hello %s!", name);
  }
}

C#

using Google.Cloud.Functions.Framework;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using System.IO;
using System.Text.Json;
using System.Threading.Tasks;

namespace HelloHttp
{
    public class Function : IHttpFunction
    {
        private readonly ILogger _logger;

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

        public async Task HandleAsync(HttpContext context)
        {
            HttpRequest request = context.Request;
            // Check URL parameters for "name" field
            // "world" is the default value
            string name = ((string) request.Query["name"]) ?? "world";

            // If there's a body, parse it as JSON and check for "name" field.
            using TextReader reader = new StreamReader(request.Body);
            string text = await reader.ReadToEndAsync();
            if (text.Length > 0)
            {
                try
                {
                    JsonElement json = JsonSerializer.Deserialize<JsonElement>(text);
                    if (json.TryGetProperty("name", out JsonElement nameElement) &&
                        nameElement.ValueKind == JsonValueKind.String)
                    {
                        name = nameElement.GetString();
                    }
                }
                catch (JsonException parseException)
                {
                    _logger.LogError(parseException, "Error parsing JSON request");
                }
            }

            await context.Response.WriteAsync($"Hello {name}!");
        }
    }
}

Estructura de eventos

Las funciones activadas por HTTP reciben eventos a través de marcos de trabajo HTTP de lenguaje idiomático. Consulta las muestras de código anteriores para obtener más información.

Próximos pasos

Consulta el Instructivo de HTTP para ver un ejemplo de cómo implementar una función de HTTP, o Funciones de HTTP a fin de obtener más información sobre cómo escribir funciones de HTTP.