Desencadenador HTTP de Azure Functions

El desencadenador HTTP permite invocar una función con una solicitud HTTP. Puede usar un desencadenador HTTP para crear API sin servidor y responder a webhooks.

El valor devuelto predeterminado para una función desencadenada por HTTP es:

  • HTTP 204 No Content con el cuerpo vacío en Functions 2.x y posterior
  • HTTP 200 OK con el cuerpo vacío en Functions 1.x

Para modificar la respuesta HTTP, configure un enlace de salida.

Para obtener más información sobre los enlaces HTTP, consulte la información general y la referencia sobre enlaces de salida.

Sugerencia

Si planea usar los enlaces HTTP o WebHook, debe evitar el agotamiento de puertos que puede deberse a la creación incorrecta de instancias de HttpClient. Para más información, consulte How to manage connections in Azure Functions (Administración de conexiones en Azure Functions).

Importante

En este artículo se usan pestañas para admitir varias versiones del modelo de programación de Node.js. El modelo v4 está disponible de forma general y está diseñado para que los desarrolladores de JavaScript y TypeScript tengan una experiencia más flexible e intuitiva. Para más detalles acerca de cómo funciona el modelo v4, consulte la Guía para desarrolladores de Node.js de Azure Functions. Para más información sobre las diferencias entre v3 y v4, consulte la Guía de migración.

Azure Functions admite dos modelos de programación para Python. La forma en que defina los enlaces depende del modelo de programación seleccionado.

El modelo de programación de Python v2 permite definir enlaces mediante decoradores directamente en el código de función de Python. Para más información, consulte la Guía para desarrolladores de Python.

En este artículo se admiten los modelos de programación.

Ejemplo

Se puede crear una función C# mediante uno de los siguientes modos de C#:

  • Modelo de trabajo aislado: función compilada en C# que se ejecuta en un proceso trabajador aislado del tiempo de ejecución. Se requiere un proceso de trabajo aislado para admitir funciones de C# ejecutándose en versiones de .NET que son y no son LTS y .NET Framework. Las extensiones para las funciones de proceso de trabajo aisladas usan espacios de nombres Microsoft.Azure.Functions.Worker.Extensions.*.
  • Modelo en curso: función C# compilada que se ejecuta en el mismo proceso que el tiempo de ejecución de Functions. En una variación de este modelo, Functions se puede ejecutar mediante el scripting de C#, que se admite principalmente para la edición del portal de C#. Las extensiones para funciones en proceso utilizan espacios de nombres Microsoft.Azure.WebJobs.Extensions.*.

El código de este artículo tiene como valor predeterminado la sintaxis de .NET Core, que se usa en Functions versión 2.x y superiores. Para obtener información sobre la sintaxis de 1.x, consulte las plantillas de Functions 1.x.

Los siguientes ejemplos muestran un desencadenador HTTP que devuelve una respuesta "Hello Word" como IActionResult, usando una integración ASP.NET Core en .NET aislado:

[Function("HttpFunction")]
public IActionResult Run(
    [HttpTrigger(AuthorizationLevel.Anonymous, "get")] HttpRequest req)
{
    return new OkObjectResult($"Welcome to Azure Functions, {req.Query["name"]}!");
}

En el ejemplo siguiente se muestra un desencadenador HTTP que devuelve una respuesta "hola mundo" como objeto HttpResponseData:

[Function(nameof(HttpFunction))]
public static HttpResponseData Run([HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequestData req,
    FunctionContext executionContext)
{
    var logger = executionContext.GetLogger(nameof(HttpFunction));
    logger.LogInformation("message logged");

    var response = req.CreateResponse(HttpStatusCode.OK);
    response.Headers.Add("Content-Type", "text/plain; charset=utf-8");
    response.WriteString("Welcome to .NET isolated worker !!");

    return response;
}

En esta sección se incluyen los ejemplos siguientes:

En los ejemplos siguientes, se muestra el enlace del desencadenador HTTP.

Lectura del parámetro desde la cadena de consulta

En este ejemplo se lee un parámetro, denominado id, desde la cadena de consulta, y se usa para generar un documento JSON devuelto al cliente, con el tipo de contenido application/json.

@FunctionName("TriggerStringGet")
public HttpResponseMessage run(
        @HttpTrigger(name = "req", 
            methods = {HttpMethod.GET}, 
            authLevel = AuthorizationLevel.ANONYMOUS)
        HttpRequestMessage<Optional<String>> request,
        final ExecutionContext context) {

    // Item list
    context.getLogger().info("GET parameters are: " + request.getQueryParameters());

    // Get named parameter
    String id = request.getQueryParameters().getOrDefault("id", "");

    // Convert and display
    if (id.isEmpty()) {
        return request.createResponseBuilder(HttpStatus.BAD_REQUEST)
                        .body("Document not found.")
                        .build();
    } 
    else {
        // return JSON from to the client
        // Generate document
        final String name = "fake_name";
        final String jsonDocument = "{\"id\":\"" + id + "\", " + 
                                        "\"description\": \"" + name + "\"}";
        return request.createResponseBuilder(HttpStatus.OK)
                        .header("Content-Type", "application/json")
                        .body(jsonDocument)
                        .build();
    }
}

Lectura del cuerpo de una solicitud POST

En este ejemplo se lee el cuerpo de una solicitud POST, como String, y se usa para generar un documento JSON devuelto al cliente, con el tipo de contenido application/json.

    @FunctionName("TriggerStringPost")
    public HttpResponseMessage run(
            @HttpTrigger(name = "req", 
              methods = {HttpMethod.POST}, 
              authLevel = AuthorizationLevel.ANONYMOUS)
            HttpRequestMessage<Optional<String>> request,
            final ExecutionContext context) {

        // Item list
        context.getLogger().info("Request body is: " + request.getBody().orElse(""));

        // Check request body
        if (!request.getBody().isPresent()) {
            return request.createResponseBuilder(HttpStatus.BAD_REQUEST)
                          .body("Document not found.")
                          .build();
        } 
        else {
            // return JSON from to the client
            // Generate document
            final String body = request.getBody().get();
            final String jsonDocument = "{\"id\":\"123456\", " + 
                                         "\"description\": \"" + body + "\"}";
            return request.createResponseBuilder(HttpStatus.OK)
                          .header("Content-Type", "application/json")
                          .body(jsonDocument)
                          .build();
        }
    }

Lectura del parámetro de una ruta

En este ejemplo se lee un parámetro obligatorio, denominado id, y un parámetro opcional name de la ruta de acceso, y se usa para generar un documento JSON devuelto al cliente, con el tipo de contenido application/json.

@FunctionName("TriggerStringRoute")
public HttpResponseMessage run(
        @HttpTrigger(name = "req", 
            methods = {HttpMethod.GET}, 
            authLevel = AuthorizationLevel.ANONYMOUS,
            route = "trigger/{id}/{name=EMPTY}") // name is optional and defaults to EMPTY
        HttpRequestMessage<Optional<String>> request,
        @BindingName("id") String id,
        @BindingName("name") String name,
        final ExecutionContext context) {

    // Item list
    context.getLogger().info("Route parameters are: " + id);

    // Convert and display
    if (id == null) {
        return request.createResponseBuilder(HttpStatus.BAD_REQUEST)
                        .body("Document not found.")
                        .build();
    } 
    else {
        // return JSON from to the client
        // Generate document
        final String jsonDocument = "{\"id\":\"" + id + "\", " + 
                                        "\"description\": \"" + name + "\"}";
        return request.createResponseBuilder(HttpStatus.OK)
                        .header("Content-Type", "application/json")
                        .body(jsonDocument)
                        .build();
    }
}

Lectura del cuerpo POJO de una solicitud POST

Este es el código para la clase ToDoItem, a la que se hace referencia en este ejemplo:


public class ToDoItem {

  private String id;
  private String description;  

  public ToDoItem(String id, String description) {
    this.id = id;
    this.description = description;
  }

  public String getId() {
    return id;
  }

  public String getDescription() {
    return description;
  }

  @Override
  public String toString() {
    return "ToDoItem={id=" + id + ",description=" + description + "}";
  }
}

En este ejemplo se lee el cuerpo de una solicitud POST. El cuerpo de la solicitud se deserializa automáticamente en un objeto ToDoItem y se devuelve al cliente, con el tipo de contenido application/json. El parámetro ToDoItem se serializa en runtime de Functions, ya que está asignado a la propiedad body de la clase HttpMessageResponse.Builder.

@FunctionName("TriggerPojoPost")
public HttpResponseMessage run(
        @HttpTrigger(name = "req", 
            methods = {HttpMethod.POST}, 
            authLevel = AuthorizationLevel.ANONYMOUS)
        HttpRequestMessage<Optional<ToDoItem>> request,
        final ExecutionContext context) {

    // Item list
    context.getLogger().info("Request body is: " + request.getBody().orElse(null));

    // Check request body
    if (!request.getBody().isPresent()) {
        return request.createResponseBuilder(HttpStatus.BAD_REQUEST)
                        .body("Document not found.")
                        .build();
    } 
    else {
        // return JSON from to the client
        // Generate document
        final ToDoItem body = request.getBody().get();
        return request.createResponseBuilder(HttpStatus.OK)
                        .header("Content-Type", "application/json")
                        .body(body)
                        .build();
    }
}

En el ejemplo siguiente se muestra una función de TypeScript de desencadenador HTTP. La función busca un parámetro name en la cadena de consulta o en el cuerpo de la solicitud HTTP.

import { app, HttpRequest, HttpResponseInit, InvocationContext } from '@azure/functions';

export async function httpTrigger1(request: HttpRequest, context: InvocationContext): Promise<HttpResponseInit> {
    context.log(`Http function processed request for url "${request.url}"`);

    const name = request.query.get('name') || (await request.text()) || 'world';

    return { body: `Hello, ${name}!` };
}

app.http('httpTrigger1', {
    methods: ['GET', 'POST'],
    authLevel: 'anonymous',
    handler: httpTrigger1,
});

En el ejemplo siguiente se muestra una función de JavaScript de desencadenador HTTP. La función busca un parámetro name en la cadena de consulta o en el cuerpo de la solicitud HTTP.

const { app } = require('@azure/functions');

app.http('httpTrigger1', {
    methods: ['GET', 'POST'],
    authLevel: 'anonymous',
    handler: async (request, context) => {
        context.log(`Http function processed request for url "${request.url}"`);

        const name = request.query.get('name') || (await request.text()) || 'world';

        return { body: `Hello, ${name}!` };
    },
});

En el ejemplo siguiente se muestra un enlace de desencadenador en un archivo function.json y una función de PowerShell. La función busca un parámetro name en la cadena de consulta o en el cuerpo de la solicitud HTTP.

{
  "bindings": [
    {
      "authLevel": "function",
      "type": "httpTrigger",
      "direction": "in",
      "name": "Request",
      "methods": [
        "get",
        "post"
      ]
    },
    {
      "type": "http",
      "direction": "out",
      "name": "Response"
    }
  ]
}
using namespace System.Net

# Input bindings are passed in via param block.
param($Request, $TriggerMetadata)

# Write to the Azure Functions log stream.
Write-Host "PowerShell HTTP trigger function processed a request."

# Interact with query parameters or the body of the request.
$name = $Request.Query.Name
if (-not $name) {
    $name = $Request.Body.Name
}

$body = "This HTTP triggered function executed successfully. Pass a name in the query string or in the request body for a personalized response."

if ($name) {
    $body = "Hello, $name. This HTTP triggered function executed successfully."
}

# Associate values to output bindings by calling 'Push-OutputBinding'.
Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
    StatusCode = [HttpStatusCode]::OK
    Body       = $body
})

En el ejemplo siguiente se muestra un enlace de desencadenador y una función de Python que usa el enlace. La función busca un parámetro name en la cadena de consulta o en el cuerpo de la solicitud HTTP. El ejemplo depende de si usa el modelo de programación de Python v1 o v2.

import azure.functions as func
import logging

app = func.FunctionApp()

@app.function_name(name="HttpTrigger1")
@app.route(route="hello", auth_level=func.AuthLevel.ANONYMOUS)
def test_function(req: func.HttpRequest) -> func.HttpResponse:
    logging.info('Python HTTP trigger function processed a request.')
    return func.HttpResponse(
        "This HTTP triggered function executed successfully.",
        status_code=200
        )

Atributos

Las bibliotecas de C# que estándentro del proceso y en un proceso de trabajo aislado usan HttpTriggerAttribute para definir en enlace del desencadenador. En su lugar, el script de C# usa un archivo de configuración function.json como se describe en la Guía de scripting de C#.

En las aplicaciones de funciones que están en un proceso de trabajo aislado, HttpTriggerAttribute admite los parámetros siguientes:

Parámetros Descripción
AuthLevel Determina qué claves, si las hubiera, deben estar presentes en la solicitud para poder invocar a la función. Para ver los valores admitidos, consulte Nivel de autorización.
Métodos Una matriz de los métodos HTTP a los que responde la función. Si no se especifica, la función responde a todos los métodos HTTP. Consulte cómo personalizar el punto de conexión HTTP.
Route Define la plantilla de ruta y controla las direcciones URL de solicitud a las que responde la función. El valor predeterminado es <functionname> si no se proporciona ninguno. Para más información, consulte cómo personalizar el punto de conexión HTTP.

Elementos Decorator

Solo se aplica al modelo de programación de Python v2.

Para las funciones de Python v2 definidas mediante un decorador, las siguientes propiedades para un desencadenador se definen en el decorador route, que agrega el enlace HttpTrigger y HttpOutput:

Propiedad Descripción
route Ruta para el punto de conexión HTTP. Si es Ninguna, se establecerá en el nombre de función si está presente o en el nombre de la función de Python definida por el usuario.
trigger_arg_name Nombre de argumento para HttpRequest. El valor predeterminado es "req".
binding_arg_name Nombre de argumento para HttpResponse. El valor predeterminado es "$return".
methods Una tupla de los métodos HTTP a los que responde la función.
auth_level Determina qué claves, si las hubiera, deben estar presentes en la solicitud para poder invocar a la función.

Para las funciones de Python definidas mediante function.json, consulte la sección Configuración.

anotaciones

En la biblioteca de tiempo de ejecución de funciones de Java, use la anotación HttpTrigger, que admite la siguiente configuración:

Configuración

Solo se aplica al modelo de programación de Python v1.

En la tabla siguiente se explican las propiedades que puede establecer en el objeto options que se pasa al métodoapp.http().

Propiedad Descripción
authLevel Determina qué claves, si las hubiera, deben estar presentes en la solicitud para poder invocar a la función. Para ver los valores admitidos, consulte Nivel de autorización.
methods Una matriz de los métodos HTTP a los que responde la función. Si no se especifica, la función responde a todos los métodos HTTP. Consulte cómo personalizar el punto de conexión HTTP.
route Define la plantilla de ruta y controla las direcciones URL de solicitud a las que responde la función. El valor predeterminado es <functionname> si no se proporciona ninguno. Para más información, consulte cómo personalizar el punto de conexión HTTP.

En la siguiente tabla se explican las propiedades de configuración del desencadenador que definió en el archivo function.json, que difiere según la versión de tiempo de ejecución.

En la siguiente tabla se explican las propiedades de configuración de enlace que se establecen en el archivo function.json.

Propiedad de function.json Descripción
type Requerida: se debe establecer en httpTrigger.
direction Requerida: se debe establecer en in.
name Requerida: nombre de variable que se usa en el código de la función para la solicitud o el cuerpo de la solicitud.
authLevel Determina qué claves, si las hubiera, deben estar presentes en la solicitud para poder invocar a la función. Para ver los valores admitidos, consulte Nivel de autorización.
methods Una matriz de los métodos HTTP a los que responde la función. Si no se especifica, la función responde a todos los métodos HTTP. Consulte cómo personalizar el punto de conexión HTTP.
route Define la plantilla de ruta y controla las direcciones URL de solicitud a las que responde la función. El valor predeterminado es <functionname> si no se proporciona ninguno. Para más información, consulte cómo personalizar el punto de conexión HTTP.

Uso

En esta sección se detalla cómo configurar el enlace de función de desencadenador HTTP.

La anotación HttpTrigger debe aplicarse a un parámetro de método de uno de los tipos siguientes:

  • HttpRequestMessage<T>.
  • Cualquier tipo nativo de Java como int, String, byte[].
  • Valores que admiten valores NULL mediante Optional.
  • Cualquier tipo POJO (plain-old Java object).

Carga

El tipo de entrada del desencadenador se declara como uno de los siguientes tipos:

Tipo Descripción
HttpRequest El uso de este tipo requiere que la aplicación esté configurada con la integración de ASP.NET Core en .NET aislado.
Esto le brinda acceso completo al objeto de solicitud y al HttpContext general.
HttpRequestData Proyección del objeto de solicitud.
Un tipo personalizado Cuando el cuerpo de la solicitud es JSON, el tiempo de ejecución intentará analizarlo para establecer las propiedades del objeto.

Cuando el parámetro de desencadenador es HttpRequestData o HttpRequest, los tipos personalizados también se pueden enlazar a parámetros adicionales mediante Microsoft.Azure.Functions.Worker.Http.FromBodyAttribute. El uso de este atributo requiere la Microsoft.Azure.Functions.Worker.Extensions.Http versión 3.1.0 o posterior. Tenga en cuenta que este es un tipo diferente al atributo similar en Microsoft.AspNetCore.Mvc, y cuando use la integración de ASP.NET Core, necesitará una referencia o using instrucción completa. El siguiente ejemplo muestra cómo usar el atributo para obtener solo el contenido del cuerpo sin dejar de tener acceso al HttpRequest completo, mediante la integración de ASP.NET Core:

using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.Functions.Worker;
using FromBodyAttribute = Microsoft.Azure.Functions.Worker.Http.FromBodyAttribute;

namespace AspNetIntegration
{
    public class BodyBindingHttpTrigger
    {
        [Function(nameof(BodyBindingHttpTrigger))]
        public IActionResult Run([HttpTrigger(AuthorizationLevel.Anonymous, "post")] HttpRequest req,
            [FromBody] Person person)
        {
            return new OkObjectResult(person);
        }
    }

    public record Person(string Name, int Age);
}

Personalización del punto de conexión HTTP

De forma predeterminada, al crear una función para un desencadenador HTTP, la función se puede dirigir con una ruta que tenga el siguiente formato:

http://<APP_NAME>.azurewebsites.net/api/<FUNCTION_NAME>

Puede personalizar esta ruta mediante el parámetro opcional route del enlace de entrada del desencadenador HTTP. Puede usar cualquier restricción de ruta de API web con sus parámetros.

El siguiente código de función acepta dos parámetros, category y id, en la ruta y escribe una respuesta con ambos parámetros.

[Function("HttpTrigger1")]
public static HttpResponseData Run([HttpTrigger(AuthorizationLevel.Function, "get", "post",
Route = "products/{category:alpha}/{id:int?}")] HttpRequestData req, string category, int? id,
FunctionContext executionContext)
{
    var logger = executionContext.GetLogger("HttpTrigger1");
    logger.LogInformation("C# HTTP trigger function processed a request.");

    var message = String.Format($"Category: {category}, ID: {id}");
    var response = req.CreateResponse(HttpStatusCode.OK);
    response.Headers.Add("Content-Type", "text/plain; charset=utf-8");
    response.WriteString(message);

    return response;
}

Los parámetros de ruta se definen mediante el valor route de la anotación HttpTrigger. El siguiente código de función acepta dos parámetros, category y id, en la ruta y escribe una respuesta con ambos parámetros.

package com.function;

import java.util.*;
import com.microsoft.azure.functions.annotation.*;
import com.microsoft.azure.functions.*;

public class HttpTriggerJava {
    public HttpResponseMessage<String> HttpTrigger(
            @HttpTrigger(name = "req",
                         methods = {"get"},
                         authLevel = AuthorizationLevel.FUNCTION,
                         route = "products/{category:alpha}/{id:int}") HttpRequestMessage<String> request,
            @BindingName("category") String category,
            @BindingName("id") int id,
            final ExecutionContext context) {

        String message = String.format("Category  %s, ID: %d", category, id);
        return request.createResponseBuilder(HttpStatus.OK).body(message).build();
    }
}

Por ejemplo, en el siguiente código de TypeScript se define una propiedad route para un desencadenador HTTP con dos parámetros, category y id. En el ejemplo se leen los parámetros de la solicitud y se devuelven sus valores en la respuesta.

import { app, HttpRequest, HttpResponseInit, InvocationContext } from '@azure/functions';

export async function httpTrigger1(request: HttpRequest, context: InvocationContext): Promise<HttpResponseInit> {
    const category = request.params.category;
    const id = request.params.id;

    return { body: `Category: ${category}, ID: ${id}` };
}

app.http('httpTrigger1', {
    methods: ['GET'],
    authLevel: 'anonymous',
    route: 'products/{category:alpha}/{id:int?}',
    handler: httpTrigger1,
});

Por ejemplo, en el siguiente código de JavaScript se define una propiedad route para un desencadenador HTTP con dos parámetros, category y id. En el ejemplo se leen los parámetros de la solicitud y se devuelven sus valores en la respuesta.

const { app } = require('@azure/functions');

app.http('httpTrigger1', {
    methods: ['GET'],
    authLevel: 'anonymous',
    route: 'products/{category:alpha}/{id:int?}',
    handler: async (request, context) => {
        const category = request.params.category;
        const id = request.params.id;

        return { body: `Category: ${category}, ID: ${id}` };
    },
});

Por ejemplo, el siguiente código define una propiedad route para un desencadenador HTTP con dos parámetros, category y id:

@app.function_name(name="httpTrigger")
@app.route(route="products/{category:alpha}/{id:int?}")

Los parámetros de ruta declarados en el archivo function.json son accesibles como una propiedad del objeto $Request.Params.

$Category = $Request.Params.category
$Id = $Request.Params.id

$Message = "Category:" + $Category + ", ID: " + $Id

Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
    StatusCode = [HttpStatusCode]::OK
    Body = $Message
})

El contexto de ejecución de la función se expone a través de un parámetro declarado como func.HttpRequest. Esta instancia permite que una función acceda a parámetros de rutas de datos, valores de cadenas de consulta y métodos que permiten devolver respuestas HTTP.

Una vez definidos, los parámetros de ruta están disponibles para la función mediante la llamada al método route_params.

import logging

import azure.functions as func

def main(req: func.HttpRequest) -> func.HttpResponse:

    category = req.route_params.get('category')
    id = req.route_params.get('id')
    message = f"Category: {category}, ID: {id}"

    return func.HttpResponse(message)

Al usar esta configuración, ya se podrá dirigir la función con la ruta de abajo, en lugar de con la original.

http://<APP_NAME>.azurewebsites.net/api/products/electronics/357

Esta configuración permite que el código de la función admita dos parámetros en la dirección: category e id. Para más información sobre cómo se tokenizan los parámetros de ruta en una dirección URL, consulte Enrutamiento en ASP.NET Core.

De forma predeterminada, todas las rutas de la función tienen el prefijo api. También puede personalizar o quitar el prefijo con la propiedad extensions.http.routePrefix del archivo host.json. En el ejemplo siguiente, se quita el prefijo de ruta api utilizando una cadena vacía del prefijo del archivo host.json.

{
    "extensions": {
        "http": {
            "routePrefix": ""
        }
    }
}

Uso de parámetros de ruta

Los parámetros de ruta que definían el patrón route de una función están disponibles para cada enlace. Por ejemplo, si tiene una ruta definida como "route": "products/{id}", un enlace de almacenamiento de tabla puede utilizar el valor del parámetro {id} en la configuración de enlace.

La configuración siguiente muestra cómo se pasa el parámetro {id} al elemento rowKey del enlace.

@app.table_input(arg_name="product", table_name="products", 
                 row_key="{id}", partition_key="products",
                 connection="AzureWebJobsStorage")
import { app, HttpRequest, HttpResponseInit, input, InvocationContext } from '@azure/functions';

const tableInput = input.table({
    connection: 'MyStorageConnectionAppSetting',
    partitionKey: 'products',
    tableName: 'products',
    rowKey: '{id}',
});

export async function httpTrigger1(request: HttpRequest, context: InvocationContext): Promise<HttpResponseInit> {
    return { jsonBody: context.extraInputs.get(tableInput) };
}

app.http('httpTrigger1', {
    methods: ['GET'],
    authLevel: 'anonymous',
    route: 'products/{id}',
    extraInputs: [tableInput],
    handler: httpTrigger1,
});
const { app, input } = require('@azure/functions');

const tableInput = input.table({
    connection: 'MyStorageConnectionAppSetting',
    partitionKey: 'products',
    tableName: 'products',
    rowKey: '{id}',
});

app.http('httpTrigger1', {
    methods: ['GET'],
    authLevel: 'anonymous',
    route: 'products/{id}',
    extraInputs: [tableInput],
    handler: async (request, context) => {
        return { jsonBody: context.extraInputs.get(tableInput) };
    },
});
{
    "type": "table",
    "direction": "in",
    "name": "product",
    "partitionKey": "products",
    "tableName": "products",
    "rowKey": "{id}"
}

Al usar parámetros de ruta, se crea automáticamente una plantilla invoke_URL_template para la función. Los clientes pueden usar la plantilla de dirección URL para comprender los parámetros que deben pasar en la dirección URL al llamar a la función mediante su dirección URL. Vaya a una de las funciones desencadenadas por HTTP en Azure Portal y seleccioneObtener la dirección URL de la función.

Puede tener acceso mediante programación a la plantilla invoke_URL_template con las API de Azure Resource Manager para List Functions (Funciones de lista) o Get Function (Get (función)).

Flujos HTTP (versión preliminar)

Ahora puede transmitir solicitudes a y respuestas desde el punto de conexión HTTP en Node.js aplicaciones de funciones v4. Para obtener más información, consulte Flujos HTTP.

Uso de identidades de cliente

Si la aplicación de función está usando la autenticación/autorización de App Service, puede ver información sobre los clientes autenticados desde el código. Esta información está disponible como encabezados de solicitud insertados por la plataforma.

También puede leer esta información desde los datos de enlace. Esta funcionalidad solo está disponible para el entorno en tiempo de ejecución de Functions en la versión 2.x y posteriores. Actualmente, también está disponible para lenguajes .NET.

La información sobre los clientes autenticados está disponible como ClaimsPrincipal, que está disponible como parte del contexto de solicitud, como se muestra en el ejemplo siguiente:

El usuario autenticado está disponible a través de encabezados HTTP.

El usuario autenticado está disponible a través de encabezados HTTP.

lista desplegable

El nivel de autorización es un valor de cadena que indica el tipo de clave de autorización necesaria para acceder al punto de conexión de la función. Para una función desencadenada por HTTP, el nivel de autorización puede ser uno de los valores siguientes:

Valor de nivel Descripción
anónimo No se requiere ninguna clave de API. Este es el valor predeterminado cuando un nivel no se establece específicamente.
function Se requiere una clave de API específica de la función.
admin Se requiere la clave maestra.
Valor de nivel Descripción
anónimo No se requiere ninguna clave de API.
function Se requiere una clave de API específica de la función. Este es el valor predeterminado cuando un nivel no se establece específicamente.
admin Se requiere la clave maestra.

Claves de acceso de función

Functions permite usar claves para dificultar el acceso a los puntos de conexión de función HTTP durante el desarrollo. A menos que el nivel de acceso HTTP en una función desencadenada por HTTP se establezca en anonymous, las solicitudes deben incluir una clave de acceso de API.

Aunque las claves proporcionan un mecanismo de seguridad predeterminado, podría plantearse la posibilidad de otras opciones para proteger un punto de conexión HTTP en producción. Por ejemplo, no es recomendable distribuir un secreto compartido en las aplicaciones públicas. Si se llama a la función desde un cliente público, puede que sea conveniente implementar otro mecanismo de seguridad. Para obtener más información, vea Proteger un punto de conexión HTTP en producción.

Al renovar los valores de la clave de función, debe redistribuir manualmente los valores de clave actualizados a todos los clientes que llaman a la función.

Ámbitos de autorización (nivel de función)

Hay dos ámbitos de acceso para las claves de nivel de función:

  • Función: estas claves se aplican solo a las funciones específicas en las que se definen. Cuando se usan como una clave de API, solo permiten el acceso a esa función.

  • Host: las claves con un ámbito de host se pueden usar para acceder a todas las funciones dentro de la aplicación de función. Cuando se usan como una clave de API, permiten el acceso a cualquier función dentro de la aplicación de función.

Para cada clave se usa un nombre fácilmente referenciable y hay una clave predeterminada (denominada "predeterminada") en el nivel de función y host. Las claves de función tienen prioridad sobre las claves de host. Si se definen dos claves con el mismo nombre, siempre se usa la clave de función.

Clave maestra (nivel de administrador)

Cada aplicación de función también tiene una clave de host de nivel de administrador denominada _master. Además de proporcionar acceso de nivel de host a todas las funciones de la aplicación, la clave maestra también proporciona acceso administrativo a las API REST del entorno de ejecución. No se puede revocar esta clave. Al establecer un nivel de acceso admin, las solicitudes deben usar la clave maestra; cualquier otra clave da lugar a un error de acceso.

Precaución

Debido a los permisos elevados de la aplicación de funciones otorgados por la clave maestra, no debe compartir esta clave con terceros ni distribuirla en aplicaciones cliente nativas. Tenga cuidado al elegir el nivel de acceso de administrador.

Obtención de claves

Las claves se almacenan como parte de la aplicación de función en Azure y se cifran en reposo. Para ver las claves, crear nuevas o asignarles nuevos valores, vaya a una de las funciones desencadenadas por HTTP de Azure Portal y seleccione Claves de función.

También puede administrar claves de host. Vaya a la aplicación de funciones de Azure Portal y seleccione Claves de la aplicación.

Puede obtener claves de función y de host mediante programación con las API de Azure Resource Manager. Hay API para List Function Keys (Enumerar claves de función) y List Host Keys (Enumerar claves de host) y, al usar ranuras de implementación, las API equivalentes son List Function Keys Slot (Enumerar ranura de claves de función) y List Host Keys Slot (Enumerar ranura de claves de host).

También puede crear nuevas claves de función y de host mediante programación con las API Create Or Update Function Secret (Crear o actualizar secreto de función) , Create Or Update Function Secret Slot (Crear o actualizar ranura de secreto de función), Create Or Update Host Secret (Crear o actualizar secreto de host) y Create Or Update Host Secret Slot (Crear o actualizar ranura de secreto de host).

Las claves de función y de host se pueden eliminar mediante programación con las API Delete Function Secret (Eliminar secreto de función), Delete Function Secret Slot (Eliminar ranura de secreto de función), Delete Host Secret (Eliminar secreto de host) y Delete Host Secret Slot (Eliminar ranura de secreto de host).

También puede usar las API de administración de claves heredadas para obtener claves de función, pero, en su lugar, se recomienda usar las API de Azure Resource Manager.

Autorización de la clave de API

La mayoría de las plantillas de desencadenador HTTP requieren una clave de API en la solicitud. Por lo tanto, la solicitud HTTP normalmente se parece a la siguiente dirección URL:

https://<APP_NAME>.azurewebsites.net/api/<FUNCTION_NAME>?code=<API_KEY>

La clave se puede incluir en una variable de cadena de consulta denominada code, como arriba. También puede incluirse en un encabezado HTTP x-functions-key. El valor de la clave puede ser cualquier clave de función definida para la función o cualquier clave de host.

Puede permitir solicitudes anónimas, que no requieren claves. También puede exigir que se use la clave maestra. Cambie el nivel de autorización predeterminado mediante la propiedad authLevel en el JSON de enlace. Para más información, consulte Desencadenador: configuración.

Nota

Cuando las funciones se ejecutan localmente, la autorización se deshabilita independientemente del valor del nivel de autorización especificado. Después de publicar en Azure, se aplica el valor authLevel del desencadenador. Las claves siguen siendo necesarias cuando se ejecutan localmente en un contenedor.

Proteger un punto de conexión HTTP en producción

Para proteger totalmente los puntos de conexión de función en producción, considere la posibilidad de implementar una de las opciones de seguridad siguientes de nivel de aplicación de función. Cuando use alguno de estos métodos de seguridad de nivel de aplicación de función, debe establecer el nivel de autorización de función desencadenado por HTTP en anonymous.

Habilitación de la autenticación o la autorización de App Service

La plataforma App Service le permite usar Microsoft Entra ID y varios proveedores de identidades de terceros para autenticar a los clientes. Se puede usar esta estrategia para implementar reglas de autorización personalizadas para las funciones y permite trabajar con información de usuario desde el código de función. Para obtener más información, vea Autenticación y autorización en Azure App Service y Uso de identidades de cliente.

Uso de Azure API Management (APIM) para autenticar solicitudes

APIM proporciona una serie de opciones de seguridad de API para las solicitudes entrantes. Para obtener más información, vea Directivas de autenticación de Azure API Management. Con APIM, puede configurar la aplicación de función de modo que solo acepte solicitudes de la dirección IP de la instancia de APIM. Para obtener más información, vea Restricciones de las direcciones IP.

Implementación de la aplicación de funciones en aislamiento

Azure App Service Environment (ASE) proporciona un entorno de hospedaje dedicado en el que ejecutar las funciones. ASE le permite configurar una puerta de enlace de front-end única que se puede usar para autenticar todas las solicitudes entrantes. Para obtener más información, vea Configuración de un firewall de aplicaciones web (WAF) para entornos de App Service.

webhooks

Nota

El modo de webhook solo está disponible para la versión 1.x del runtime de Functions. Este cambio se realizó para mejorar el rendimiento de los desencadenadores HTTP en la versión 2.x y posteriores.

En la versión 1.x, las plantillas de webhook proporcionan una validación adicional para las cargas de webhook. En la versión 2.x y posteriores, el desencadenador HTTP base todavía funciona y es el modo recomendado para webhooks.

Tipo de webhook

La propiedad de enlace webHookType indica el tipo si el webhook es compatible con la función, lo que también dicta la carga útil admitida. El tipo de webhook puede ser uno de los valores siguientes:

Valor del tipo Descripción
genericJson Un punto de conexión de webhook de uso general sin lógica para un proveedor concreto. Este valor restringe las solicitudes a solo aquellas que usan HTTP POST y con el tipo de contenido application/json.
github La función responde a webhooks de GitHub. No use la propiedad authLevel con webhooks de GitHub.
slack La función responde a webhooks de Slack. No use la propiedad authLevel con webhooks de Slack.

Al establecer la propiedad webHookType, no establezca también la propiedad methods en el enlace.

Webhooks de GitHub

Para responder a webhooks de GitHub, primero cree la función con un desencadenador HTTP y establezca la propiedad webHookType en github. Luego copie su dirección URL y clave de API en la página Agregar webhook del repositorio GitHub.

Screenshot that shows how to add a webhook for your function.

Webhooks de Slack

El webhook de Slack genera un token en lugar de permitirle especificarlo, por lo que debe configurar una clave específica de función con el token desde Slack. Consulte Claves de autorización.

Webhooks y claves

La autorización de webhook se controla mediante el componente receptor de webhook, parte del desencadenador HTTP; el mecanismo varía según el tipo de webhook. Cada mecanismo se basa en una clave. De forma predeterminada, se usa la clave de función denominada "default". Para usar otra clave, configure el proveedor de webhook de modo que envíe el nombre de la clave con la solicitud de una de las siguientes maneras:

  • Cadena de consulta: el proveedor pasa el nombre de la clave en el parámetro de la cadena de consulta clientid, como https://<APP_NAME>.azurewebsites.net/api/<FUNCTION_NAME>?clientid=<KEY_NAME>.
  • Encabezado de solicitud: el proveedor pasa el nombre de clave en el encabezado x-functions-clientid.

Tipos de contenido

Para pasar datos binarios y de formulario a una función que no es de C#, es necesario utilizar el encabezado Content-Type adecuado. Los tipos de contenido admitidos incluyen octet-stream para los datos binarios y tipos de varias partes.

Problemas conocidos

En las funciones que no son de C#, las solicitudes enviadas con el tipo de contenido image/jpeg producen un valor string pasado a la función. En casos como estos, puede convertir manualmente el valor string en una matriz de bytes para acceder a los datos binarios sin formato.

Límites

La longitud de la solicitud HTTP está limitada a 100 MB (104 857 600 bytes) y la longitud de la dirección URL a 4 KB (4 096 bytes). El elemento httpRuntime del archivo Web.config especifica estos límites.

Si una función que usa el desencadenador HTTP no se completa en menos de 230 segundos, Azure Load Balancer agotará el tiempo de espera y devolverá un error HTTP 502. La función seguirá ejecutándose, pero no podrá devolver una respuesta HTTP. En el caso de funciones de ejecución prolongada, se recomienda que siga patrones asincrónicos y que devuelva una ubicación donde pueda hacer ping con el estado de la solicitud. Para más información sobre cuánto tiempo se puede ejecutar una función, consulte Escalado y hospedaje: Plan de consumo.

Pasos siguientes