

# Estructura de eventos de CloudFront Functions
<a name="functions-event-structure"></a>

CloudFront Functions pasa un objeto `event` al código de función como entrada cuando ejecuta la función. Cuando [prueba una función](test-function.md), crea el objeto `event` y lo pasa a la función. Al crear un objeto `event` para probar una función, puede omitir los campos `distributionDomainName`,`distributionId` y`requestId` en el objeto `context`. Asegúrese de que los nombres de encabezados estén en minúsculas, esto siempre sucede en el objeto de `event` que CloudFront Functions pasa a la función en producción.

A continuación, se muestra la información general de la estructura de este objeto de evento. 

```
{
    "version": "1.0",
    "context": {
        <context object>
    },
    "viewer": {
        <viewer object>
    },
    "request": {
        <request object>
    },
    "response": {
        <response object>
    }
}
```

Para obtener más información, consulte los temas siguientes:

**Topics**
+ [Campo Versión](#functions-event-structure-version)
+ [Objeto Context (Contexto)](#functions-event-structure-context)
+ [Estructura de eventos de conexión](#functions-event-structure-connection)
+ [Objeto viewer (lector)](#functions-event-structure-viewer)
+ [Objeto Request (solicitud)](#functions-event-structure-request)
+ [Objeto de respuesta](#functions-event-structure-response)
+ [Código de estado y cuerpo](#functions-event-structure-status-body)
+ [Estructura para una cadena de consulta, encabezado o cookie](#functions-event-structure-query-header-cookie)
+ [Objeto de respuesta de ejemplo](#functions-response-structure-example)
+ [Objeto de evento de ejemplo](#functions-event-structure-example)

## Campo Versión
<a name="functions-event-structure-version"></a>

El campo `version` contiene una cadena que especifica la versión del objeto de evento de CloudFront Functions. La versión actual es `1.0`.

## Objeto Context (Contexto)
<a name="functions-event-structure-context"></a>

El objeto `context` contiene información contextual sobre el evento. Contiene los campos siguientes:

**`distributionDomainName`**  
El nombre de dominio de CloudFront (por ejemplo, d111111abcdef8.cloudfront.net) de la distribución que está asociada al evento.  
El campo `distributionDomainName` solo aparece cuando se invoca la función para distribuciones estándar.

**`endpoint`**  
El nombre de dominio de CloudFront (por ejemplo, d111111abcdef8.cloudfront.net) del grupo de conexión asociado al evento.  
El campo `endpoint` solo aparece cuando se invoca la función para distribuciones de varios inquilinos.

**`distributionId`**  
El identificador de la distribución (por ejemplo, EDFDVBD6EXAMPLE) que está asociada al evento.

**`eventType`**  
El tipo de evento, `viewer-request` o `viewer-response`.

**`requestId`**  
Cadena que identifica de forma única una solicitud de CloudFront (y su respuesta asociada).

## Estructura de eventos de conexión
<a name="functions-event-structure-connection"></a>

Las funciones de conexión reciben una estructura de eventos diferente a la de las funciones del espectador. Para obtener información detallada sobre la estructura de eventos de conexión y el formato de respuesta, consulte [Asociación de una función de conexión de CloudFront](connection-functions.md).

## Objeto viewer (lector)
<a name="functions-event-structure-viewer"></a>

El objeto `viewer` contiene un campo `ip` cuyo valor es la dirección IP del lector (cliente) que envió la solicitud. Si el lector utiliza un proxy HTTP o un balanceador de carga para enviar la solicitud, el valor es la dirección IP del proxy o del balanceador de carga.

## Objeto Request (solicitud)
<a name="functions-event-structure-request"></a>

El objeto `request` contiene una representación de una solicitud HTTP de lector-a-CloudFront. En el objeto `event` que se pasa a la función, el objeto `request` representa la solicitud real que CloudFront recibió del lector.

Si su código de función devuelve un objeto `request` a CloudFront, debe usar esta misma estructura.

El objeto `request` contiene los siguientes campos:

**`method`**  
El método HTTP de la solicitud. Si su código de función devuelve una `request`, no puede modificar este campo. Este es el único campo de solo lectura en el objeto `request`.

**`uri`**  
La ruta relativa del objeto solicitado.   
Si la función modifica el valor `uri`, se aplica lo siguiente:  
+ El nuevo valor `uri` debe comenzar con una barra diagonal (`/`).
+ Si una función cambia el valor de `uri`, esta cambia el objeto que el lector solicita.
+ Si una función cambia el valor de `uri`, *no* cambia el comportamiento de la caché de la solicitud ni del origen al que se envía la solicitud.

**`querystring`**  
Objeto que representa la cadena de consulta en la solicitud. Si la solicitud no incluye una cadena de consulta, el objeto `request` del evento incluye un valor `querystring` vacío.  
El objeto `querystring` contiene un campo para cada parámetro de cadena de consulta de la solicitud.

**`headers`**  
Objeto que representa el encabezado HTTP en la solicitud. Si la solicitud contiene algún encabezado `Cookie`, esos encabezados no forman parte del objeto `headers`. Las cookies se representan por separado en el objeto `cookies`.  
El objeto `headers` contiene un campo para cada encabezado de la solicitud. Los nombres de encabezados se convierten a ASCII minúsculas en el objeto de evento; deben estar en ASCII minúsculas cuando se agregan según el código de función. Cuando CloudFront Functions convierte el objeto de evento de nuevo en una solicitud HTTP, la primera letra de cada palabra en los nombres de encabezados se escribe en mayúsculas, si es una letra ASCII. CloudFront Functions no aplica ningún cambio a los símbolos que no sean ASCII en los nombres de los encabezados. Por ejemplo, `TÈst-header` se convertirá en `tÈst-header` dentro de la función. El símbolo que no es ASCII `È` permanece inalterado.  
Las palabras están separadas por un guión (`-`). Por ejemplo, si el código de la función agrega un encabezado llamado `example-header-name`, CloudFront lo convierte en `Example-Header-Name` en la solicitud HTTP.

**`cookies`**  
Objeto que representa las cookies en la solicitud (encabezados `Cookie`).  
El objeto `cookies` contiene un campo para cada cookie de la solicitud.

Para obtener más información sobre la estructura de cadenas de consulta, encabezados y cookies, consulte [Estructura para una cadena de consulta, encabezado o cookie](#functions-event-structure-query-header-cookie).

Para obtener un objeto de ejemplo `event`, consulte [Objeto de evento de ejemplo](#functions-event-structure-example).

## Objeto de respuesta
<a name="functions-event-structure-response"></a>

El objeto `response` contiene una representación de una respuesta HTTP CloudFront-to-viewer. En el objeto `event` que se pasa a la función, el objeto `response` representa la respuesta real de CloudFront a una solicitud del lector.

Si su código de función devuelve un objeto `response`, debe usar esta misma estructura.

El objeto `response` contiene los siguientes campos:

**`statusCode`**  
Código de estado HTTP de la respuesta. Este valor es un número entero, no una cadena.  
La función puede generar o modificar el `statusCode`.

**`statusDescription`**  
La descripción del estado HTTP de la respuesta. Si su código de función genera una respuesta, este campo es opcional.

**`headers`**  
Un objeto que representa los encabezados HTTP en la solicitud. Si la respuesta contiene algún encabezado `Set-Cookie`, esos encabezados no forman parte del objeto `headers`. Las cookies se representan por separado en el objeto `cookies`.  
El objeto `headers` contiene un campo para cada encabezado de la respuesta. Los nombres de encabezados se convierten a minúsculas en el objeto de evento; deben estar en minúsculas cuando se agregan con el código de función. Cuando CloudFront Functions convierte el objeto de evento de nuevo en una respuesta HTTP, la primera letra de cada palabra en los nombres de encabezados se escribe en mayúsculas. Las palabras están separadas por un guión (`-`). Por ejemplo, si el código de la función agrega un encabezado llamado `example-header-name`, CloudFront lo convierte en `Example-Header-Name` en la respuesta HTTP.

**`cookies`**  
Objeto que representa las cookies en la respuesta (encabezados `Set-Cookie`).  
El objeto `cookies` contiene un campo para cada cookie en la respuesta.

**`body`**  
Agregar el campo `body` es opcional y no estará presente en el objeto de `response` a menos que lo especifique en la función. La función no tiene acceso al cuerpo original devuelto por la caché o el origen de CloudFront. Si no especifica el campo `body` en la función de respuesta del lector, el cuerpo original devuelto por la memoria caché o el origen de CloudFront se devuelve al lector.  
Si desea que CloudFront devuelva un cuerpo personalizado al lector, especifique el contenido del cuerpo en el campo `data` y la codificación del cuerpo en el campo `encoding`. Puede especificar la codificación como texto sin formato (`"encoding": "text"`) o como contenido cifrado en Base64 (`"encoding": "base64"`).  
Como método abreviado, también puede especificar el contenido del cuerpo directamente en el campo `body` (`"body": "<specify the body content here>"`). Al hacer esto, omita los campos `data` y `encoding`. CloudFront trata el cuerpo como texto sin formato en este caso.    
`encoding`  
La codificación del contenido de `body` (campo `data`). Las únicas codificaciones válidas son `text` y `base64`.  
Si especifica `encoding` como `base64` pero el cuerpo no tiene una codificación base64 válida, CloudFront devuelve un error.  
`data`  
El contenido de `body`.

Para obtener más información sobre los códigos de estado y el contenido del cuerpo modificados, consulte [Código de estado y cuerpo](#functions-event-structure-status-body).

Para obtener más información sobre la estructura de los encabezados y las cookies, consulte [Estructura para una cadena de consulta, encabezado o cookie](#functions-event-structure-query-header-cookie).

Para obtener un objeto de ejemplo `response`, consulte [Objeto de respuesta de ejemplo](#functions-response-structure-example).

## Código de estado y cuerpo
<a name="functions-event-structure-status-body"></a>

Con CloudFront Functions, puede actualizar el código de estado de la respuesta del lector, sustituir todo el cuerpo de la respuesta por uno nuevo o eliminar el cuerpo de la respuesta. Algunos escenarios comunes para actualizar la respuesta del lector después de evaluar aspectos de la respuesta de la caché o el origen de CloudFront son los siguientes:
+ Cambiar el estado para establecer un código de estado HTTP 200 y crear un cuerpo con contenido estático para devolverlo al lector.
+ Cambiar el estado para establecer un código de estado HTTP 301 o 302 para redirigir al usuario a otro sitio web.
+ Decidir si mostrar o dejar el cuerpo de la respuesta del lector.

**nota**  
Si el origen devuelve un error HTTP igual o superior a 400, CloudFront Function no se ejecutará. Para obtener más información consulte () [Restricciones en todas las funciones de borde](edge-function-restrictions-all.md).

Cuando trabaja con la respuesta HTTP, CloudFront Functions no tiene acceso al cuerpo de la respuesta. Puede sustituir el contenido del cuerpo estableciéndolo en el valor deseado o puede eliminar el cuerpo estableciendo un valor vacío. Si no actualiza el campo cuerpo de la función, el cuerpo original devuelto por la caché o el origen de CloudFront se devuelve al lector.

**sugerencia**  
Cuando utilice CloudFront Functions para sustituir un cuerpo, asegúrese de alinear los encabezados correspondientes, como `content-encoding`, `content-type` o `content-length` con el nuevo contenido del cuerpo.   
Por ejemplo, si el origen o la caché de CloudFront devuelve `content-encoding: gzip` pero la función de respuesta del lector establece un cuerpo que es texto sin formato, la función también debe cambiar los encabezados `content-encoding` y `content-type` en consecuencia.

Si CloudFront Function está configurada para devolver un error HTTP igual o superior a 400, el visor no verá una [página de error personalizada](creating-custom-error-pages.md) que haya especificado para el mismo código de estado.

## Estructura para una cadena de consulta, encabezado o cookie
<a name="functions-event-structure-query-header-cookie"></a>

Las cadenas de consulta, los encabezados y las cookies comparten la misma estructura. Las cadenas de consulta pueden aparecer en las solicitudes. Los encabezados aparecen en las solicitudes y las respuestas. Las cookies aparecen en las solicitudes y las respuestas.

Cada cadena de consulta, encabezado o cookie es un campo único dentro del objeto principal `querystring`,`headers` o `cookies`. El nombre del campo es el nombre de la cadena de consulta, el encabezado o la cookie. Cada campo contiene una propiedad `value` con el valor de la cadena de consulta, el encabezado o la cookie.

**Contents**
+ [Valores de cadenas de consulta u objetos de cadenas de consulta](#functions-event-structure-query)
+ [Consideraciones especiales sobre el uso de los encabezados](#functions-event-structure-headers)
+ [Cadenas de consulta, encabezados y cookies duplicados (matriz `multiValue`)](#functions-event-structure-multivalue)
+ [Atributos de cookie](#functions-event-structure-cookie-attributes)

### Valores de cadenas de consulta u objetos de cadenas de consulta
<a name="functions-event-structure-query"></a>

Una función puede devolver un valor de cadena de consulta además de un objeto de cadena de consulta. El valor de la cadena de consulta se puede utilizar para organizar los parámetros de la cadena de consulta en cualquier orden personalizado. 

**Example Ejemplo**  
Para modificar una cadena de consulta en el código de función, use código como el siguiente.  

```
var request = event.request; 
request.querystring = 'ID=42&Exp=1619740800&TTL=1440&NoValue=&querymv=val1&querymv=val2,val3';
```

### Consideraciones especiales sobre el uso de los encabezados
<a name="functions-event-structure-headers"></a>

Solo en el caso de encabezados, los nombres de encabezados se convierten a minúsculas en el objeto de evento; deben estar en minúsculas cuando se agregan con el código de función. Cuando CloudFront Functions convierte el objeto de evento de nuevo en una solicitud o respuesta HTTP, la primera letra de cada palabra en los nombres de encabezados se escribe en mayúsculas. Las palabras están separadas por un guión (`-`). Por ejemplo, si el código de la función agrega un encabezado llamado `example-header-name`, CloudFront lo convierte en `Example-Header-Name` en la solicitud o respuesta HTTP.

**Example Ejemplo**  
Considere el siguiente encabezado `Host` en una solicitud HTTP.  

```
Host: video.example.com
```
Este encabezado se representa de la siguiente manera en el objeto `request`:  

```
"headers": {
    "host": {
        "value": "video.example.com"
    }
}
```
Para acceder al encabezado `Host` en su código de función, use código como el siguiente:  

```
var request = event.request;
var host = request.headers.host.value;
```
Para agregar o modificar un encabezado en su código de función, use código como el siguiente (este código agrega un encabezado llamado `X-Custom-Header` con el valor `example value`):  

```
var request = event.request;
request.headers['x-custom-header'] = {value: 'example value'};
```

### Cadenas de consulta, encabezados y cookies duplicados (matriz `multiValue`)
<a name="functions-event-structure-multivalue"></a>

Una solicitud o respuesta HTTP puede contener más de una cadena de consulta, encabezado o cookie con el mismo nombre. En este caso, las cadenas de consulta duplicadas, encabezados o cookies se contraen en un campo del objeto `request` o `response`, pero este campo contiene una propiedad adicional denominada `multiValue`. La propiedad `multiValue` contiene una matriz con los valores de cada una de las cadenas de consulta duplicadas, encabezados o cookies.

**Example Ejemplo**  
Considere una solicitud HTTP con los siguientes encabezados `Accept`.  

```
Accept: application/json
Accept: application/xml
Accept: text/html
```
Estos encabezados se representan de la siguiente manera en el objeto `request`.  

```
"headers": {
    "accept": {
        "value": "application/json",
        "multiValue": [
            {
                "value": "application/json"
            },
            {
                "value": "application/xml"
            },
            {
                "value": "text/html"
            }
        ]
    }
}
```

**nota**  
El primer valor de encabezado (en este caso, `application/json`) se repite en las propiedades `value` y `multiValue`. Esto le permite acceder a *todos * los valores al recorrer la matriz `multiValue`.

Si el código de función modifica una cadena de consulta, encabezado o cookie que tiene una matriz `multiValue`, CloudFront Functions utiliza las siguientes reglas para aplicar los cambios:

1. Si la matriz `multiValue` existe y tiene alguna modificación, entonces esa modificación se aplica. El primer elemento de la propiedad `value` se ignora.

1. De lo contrario, se aplicará cualquier modificación a la propiedad `value` y los valores subsiguientes (si existen) permanecen sin cambios.

La propiedad `multiValue` se utiliza solo cuando la solicitud o respuesta HTTP contiene cadenas de consulta, encabezados o cookies duplicados con el mismo nombre, como se muestra en el ejemplo anterior. Sin embargo, si hay varios valores en una sola cadena de consulta, encabezado o cookie, la propiedad `multiValue` no se utiliza.

**Example Ejemplo**  
Considere una solicitud con un encabezado `Accept` que contenga tres valores.  

```
Accept: application/json, application/xml, text/html
```
Este encabezado se representa de la siguiente manera en el objeto `request`.  

```
"headers": {
    "accept": {
        "value": "application/json, application/xml, text/html"
    }
}
```

### Atributos de cookie
<a name="functions-event-structure-cookie-attributes"></a>

En un encabezado `Set-Cookie` de una respuesta HTTP, el encabezado contiene el par nombre-valor para la cookie y opcionalmente un conjunto de atributos separados por punto y coma. 

**Example Ejemplo**  

```
Set-Cookie: cookie1=val1; Secure; Path=/; Domain=example.com; Expires=Wed, 05 Apr 2021 07:28:00 GMT
```
En el objeto `response`, estos atributos se representan en la propiedad `attributes` del campo cookie. Por ejemplo, el encabezado `Set-Cookie` anterior se representa de la siguiente manera:  

```
"cookie1": {
    "value": "val1",
    "attributes": "Secure; Path=/; Domain=example.com; Expires=Wed, 05 Apr 2021 07:28:00 GMT"
}
```

## Objeto de respuesta de ejemplo
<a name="functions-response-structure-example"></a>

En el siguiente ejemplo se muestra un objeto `response` (el resultado de una función de respuesta del lector) en el que el cuerpo se ha sustituido por una función de respuesta del lector.

```
{
  "response": {
    "statusCode": 200,
    "statusDescription": "OK",
    "headers": {
      "date": {
        "value": "Mon, 04 Apr 2021 18:57:56 GMT"
      },
      "server": {
        "value": "gunicorn/19.9.0"
      },
      "access-control-allow-origin": {
        "value": "*"
      },
      "access-control-allow-credentials": {
        "value": "true"
      },
      "content-type": {
        "value": "text/html"
      },
      "content-length": {
        "value": "86"
      }
    },
    "cookies": {
      "ID": {
        "value": "id1234",
        "attributes": "Expires=Wed, 05 Apr 2021 07:28:00 GMT"
      },
      "Cookie1": {
        "value": "val1",
        "attributes": "Secure; Path=/; Domain=example.com; Expires=Wed, 05 Apr 2021 07:28:00 GMT",
        "multiValue": [
          {
            "value": "val1",
            "attributes": "Secure; Path=/; Domain=example.com; Expires=Wed, 05 Apr 2021 07:28:00 GMT"
          },
          {
            "value": "val2",
            "attributes": "Path=/cat; Domain=example.com; Expires=Wed, 10 Jan 2021 07:28:00 GMT"
          }
        ]
      }
    },
    
    // Adding the body field is optional and it will not be present in the response object
    // unless you specify it in your function.
    // Your function does not have access to the original body returned by the CloudFront
    // cache or origin.
    // If you don't specify the body field in your viewer response function, the original
    // body returned by the CloudFront cache or origin is returned to viewer.

     "body": {
      "encoding": "text",
      "data": "<!DOCTYPE html><html><body><p>Here is your custom content.</p></body></html>"
    }
  }
}
```

## Objeto de evento de ejemplo
<a name="functions-event-structure-example"></a>

En el siguiente ejemplo se muestra un objeto `event` completo. Este es un ejemplo de invocación para una distribución estándar y no para una distribución de varios inquilinos. Para distribuciones de varios inquilinos, se utiliza el campo `endpoint` en lugar de `distributionDomainName`. El valor de `endpoint` es el nombre de dominio de CloudFront (por ejemplo, d111111abcdef8.cloudfront.net) del grupo de conexiones asociado al evento.

**nota**  
El objeto `event` es la entrada a su función. Su función devuelve solo el objeto `request` o `response`, no el objeto `event` completo.

```
{
    "version": "1.0",
    "context": {
        "distributionDomainName": "d111111abcdef8.cloudfront.net",
        "distributionId": "EDFDVBD6EXAMPLE",
        "eventType": "viewer-response",
        "requestId": "EXAMPLEntjQpEXAMPLE_SG5Z-EXAMPLEPmPfEXAMPLEu3EqEXAMPLE=="
    },
    "viewer": {"ip": "198.51.100.11"},
    "request": {
        "method": "GET",
        "uri": "/media/index.mpd",
        "querystring": {
            "ID": {"value": "42"},
            "Exp": {"value": "1619740800"},
            "TTL": {"value": "1440"},
            "NoValue": {"value": ""},
            "querymv": {
                "value": "val1",
                "multiValue": [
                    {"value": "val1"},
                    {"value": "val2,val3"}
                ]
            }
        },
        "headers": {
            "host": {"value": "video.example.com"},
            "user-agent": {"value": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:83.0) Gecko/20100101 Firefox/83.0"},
            "accept": {
                "value": "application/json",
                "multiValue": [
                    {"value": "application/json"},
                    {"value": "application/xml"},
                    {"value": "text/html"}
                ]
            },
            "accept-language": {"value": "en-GB,en;q=0.5"},
            "accept-encoding": {"value": "gzip, deflate, br"},
            "origin": {"value": "https://website.example.com"},
            "referer": {"value": "https://website.example.com/videos/12345678?action=play"},
            "cloudfront-viewer-country": {"value": "GB"}
        },
        "cookies": {
            "Cookie1": {"value": "value1"},
            "Cookie2": {"value": "value2"},
            "cookie_consent": {"value": "true"},
            "cookiemv": {
                "value": "value3",
                "multiValue": [
                    {"value": "value3"},
                    {"value": "value4"}
                ]
            }
        }
    },
    "response": {
        "statusCode": 200,
        "statusDescription": "OK",
        "headers": {
            "date": {"value": "Mon, 04 Apr 2021 18:57:56 GMT"},
            "server": {"value": "gunicorn/19.9.0"},
            "access-control-allow-origin": {"value": "*"},
            "access-control-allow-credentials": {"value": "true"},
            "content-type": {"value": "application/json"},
            "content-length": {"value": "701"}
        },
        "cookies": {
            "ID": {
                "value": "id1234",
                "attributes": "Expires=Wed, 05 Apr 2021 07:28:00 GMT"
            },
            "Cookie1": {
                "value": "val1",
                "attributes": "Secure; Path=/; Domain=example.com; Expires=Wed, 05 Apr 2021 07:28:00 GMT",
                "multiValue": [
                    {
                        "value": "val1",
                        "attributes": "Secure; Path=/; Domain=example.com; Expires=Wed, 05 Apr 2021 07:28:00 GMT"
                    },
                    {
                        "value": "val2",
                        "attributes": "Path=/cat; Domain=example.com; Expires=Wed, 10 Jan 2021 07:28:00 GMT"
                    }
                ]
            }
        }
    }
}
```