

# Asignación de las transformaciones de plantillas de asignación para las API de REST en API Gateway
<a name="models-mappings"></a>

Las transformaciones de plantillas de asignación utilizan una plantilla de asignación para modificar la solicitud de integración o respuesta de integración. Una *plantilla de asignación* es un script expresado en [Velocity Template Language (VTL)](https://velocity.apache.org/engine/devel/vtl-reference.html) y aplicado a una carga útil mediante [JSONPath](https://goessner.net/articles/JsonPath/) basado en el encabezado `Content-type`. Utiliza plantillas de asignación cuando utiliza las transformaciones de plantillas de asignación. En esta sección se describe la información conceptual relacionada con las plantillas de asignación.

En el siguiente diagrama se muestra el ciclo de vida de la solicitud de un recurso `POST /pets` que tiene una integración con un punto de conexión de integración de PetStore. En esta API, un usuario envía datos sobre una mascota y el punto de conexión de integración devuelve la tarifa de adopción asociada a una mascota. En este ciclo de vida de la solicitud, las transformaciones de plantillas de asignación filtran el cuerpo de la solicitud al punto de conexión de integración y filtran el cuerpo de la respuesta desde el punto de conexión de integración.

![\[Ciclo de vida de solicitud de ejemplo\]](http://docs.aws.amazon.com/es_es/apigateway/latest/developerguide/images/mapping-template-transforms.png)


En esta sección se explica el ciclo de vida de la solicitud y la respuesta.

## Solicitud de método y solicitud de integración
<a name="models-mappings-request"></a>

En el ejemplo anterior, si este es el cuerpo de solicitud enviado al método de solicitud:

```
POST /pets
    HTTP/1.1
    Host:abcd1234.us-west-2.amazonaws.com
    Content-type: application/json
    
  {
    "id": 1,
    "type": "dog",
    "Age": 11,
  }
```

Este cuerpo de solicitud no tiene el formato correcto para que lo utilice el punto de conexión de integración, por lo que API Gateway realiza las transformaciones de plantilla de asignación. API Gateway solo realiza las transformaciones de plantilla de asignación porque hay una plantilla de asignación definida para Content-Type `application/json`. Si no define una plantilla de asignación para Content-Type, de forma predeterminada, API Gateway pasa el cuerpo a través de la solicitud de integración al punto de conexión de integración. Para modificar este comportamiento, consulte [Comportamiento de solicitud de método para cargas útiles sin plantillas de asignación para las API de REST en API Gateway](integration-passthrough-behaviors.md).

La siguiente plantilla de asignación transforma los datos de solicitud de método en la solicitud de integración antes de que se envíen al punto de conexión de integración:

```
#set($inputRoot = $input.path('$'))
  {
    "dogId" : "dog_"$elem.id,
    "Age": $inputRoot.Age
  }
```

1. La variable `$inputRoot` representa el objeto raíz en los datos JSON originales de la sección anterior. Las directivas comienzan con el símbolo `#`.

1. El valor `dog` es una concatenación del `id` del usuario y un valor de cadena.

1. `Age` es del cuerpo de solicitud de método.

A continuación, se reenvía el siguiente resultado al punto de conexión de integración:

```
{
    "dogId" : "dog_1",
    "Age": 11
  }
```

## Respuesta de integración y respuesta de método
<a name="models-mappings-response"></a>

Después de que la solicitud se haya enviado correctamente al punto de conexión de integración, el punto de conexión envía una respuesta a la respuesta de integración de API Gateway. A continuación, se muestran los datos de salida de ejemplo del punto de conexión de integración:

```
{
    "dogId" : "dog_1",
    "adoptionFee": 19.95,
}
```

La respuesta de método espera una carga útil diferente a la que devuelve la respuesta de integración. API Gateway realiza las transformaciones de plantillas de asignación. API Gateway solo realiza las transformaciones de plantilla de asignación porque hay una plantilla de asignación definida para Content-Type `application/json`. Si no define una plantilla de asignación para Content-Type, de forma predeterminada, API Gateway pasa el cuerpo a través de la respuesta de integración a la respuesta de método. Para modificar este comportamiento, consulte [Comportamiento de solicitud de método para cargas útiles sin plantillas de asignación para las API de REST en API Gateway](integration-passthrough-behaviors.md).

```
#set($inputRoot = $input.path('$'))
  {
    "adoptionFee" : $inputRoot.adoptionFee,
  }
```

El siguiente resultado se envía a la respuesta del método:

```
{"adoptionFee": 19.95}
```

Esto completa el ejemplo de transformación de plantilla de asignación. Recomendamos que, cuando sea posible, en lugar de utilizar las transformaciones de plantilla de asignación, utilice una integración de proxy para transformar los datos. Para obtener más información, consulte [Elegir un tipo de integración de API de API Gateway](api-gateway-api-integration-types.md).

# Comportamiento de solicitud de método para cargas útiles sin plantillas de asignación para las API de REST en API Gateway
<a name="integration-passthrough-behaviors"></a>

Si la solicitud de método tiene una carga útil y no tiene una plantilla de asignación definida para el encabezado `Content-Type`, puede elegir pasar la carga útil de la solicitud suministrada por el cliente a través de la solicitud de integración al backend sin transformación. Este proceso se denomina "acceso directo a la integración". 

 El comportamiento de acceso directo real de una solicitud entrante viene determinado por esta configuración. Hay tres opciones: 

**Cuando ninguna plantilla coincide con el encabezado Tipo de contenido solicitado**  
Elija esta opción si desea que el cuerpo de la solicitud de método se transmita a través de la solicitud de integración al backend sin transformación cuando el tipo de contenido de la solicitud de método no coincida con ningún tipo de contenido asociado a las plantillas de mapeo.  
Al llamar a la API de API Gateway, se elige esta opción estableciendo `WHEN_NO_MATCH` como el valor de la propiedad `passthroughBehavior` en [Integración](https://docs.aws.amazon.com/apigateway/latest/api/API_Integration.html).

**Cuando no hay plantillas definidas (recomendado)**  
Elija esta opción si desea que el cuerpo de la solicitud de método se transmita a través de la solicitud de integración al backend sin transformación cuando no se haya definido ninguna plantilla de mapeo en la solicitud de integración. Si se define una plantilla cuando se selecciona esta opción, la solicitud de método con una carga útil y un tipo de contenido que no coincida con ninguna plantilla de asignación definida se rechazará con una respuesta HTTP 415 Tipo de medio no admitido.  
Al llamar a la API de API Gateway, se elige esta opción estableciendo `WHEN_NO_TEMPLATES` como el valor de la propiedad `passthroughBehavior` en [Integración](https://docs.aws.amazon.com/apigateway/latest/api/API_Integration.html).

**Nunca**  
Elija esta opción si no desea que el cuerpo de la solicitud de método se transmita a través de la solicitud de integración al backend sin transformación cuando no se haya definido ninguna plantilla de mapeo en la solicitud de integración. Si se define una plantilla cuando esta opción está seleccionada, la solicitud de método de un tipo de contenido sin asignar se rechazará con una respuesta HTTP 415 Unsupported Media Type.   
Al llamar a la API de API Gateway, se elige esta opción estableciendo `NEVER` como el valor de la propiedad `passthroughBehavior` en [Integración](https://docs.aws.amazon.com/apigateway/latest/api/API_Integration.html).

 Los siguientes ejemplos muestran los posibles comportamientos del acceso directo. 

Ejemplo 1: Se define una plantilla de asignación en la solicitud de integración para el tipo de contenido `application/json`.


| content-type | Opción de acceso directo | Comportamiento | 
| --- | --- | --- | 
| Ninguno El valor predeterminado de API Gateway es `application/json` | WHEN\$1NO\$1MATCH | La carga de solicitud se transforma mediante la plantilla. | 
| Ninguno El valor predeterminado de API Gateway es `application/json` | WHEN\$1NO\$1TEMPLATES | La carga de solicitud se transforma mediante la plantilla. | 
| Ninguno El valor predeterminado de API Gateway es `application/json` | NEVER | La carga de solicitud se transforma mediante la plantilla. | 
| application/json | WHEN\$1NO\$1MATCH | La carga de solicitud se transforma mediante la plantilla. | 
| application/json | WHEN\$1NO\$1TEMPLATES | La carga de solicitud se transforma mediante la plantilla. | 
| application/json | NEVER | La carga de solicitud se transforma mediante la plantilla. | 
| application/xml | WHEN\$1NO\$1MATCH | La carga de solicitud no se transforma y se envía al backend tal como está. | 
| application/xml | WHEN\$1NO\$1TEMPLATES | La solicitud se rechaza con una respuesta HTTP 415 Unsupported Media Type. | 
| application/xml | NEVER | La solicitud se rechaza con una respuesta HTTP 415 Unsupported Media Type. | 

Ejemplo 2: Se define una plantilla de asignación en la solicitud de integración para el tipo de contenido `application/xml`.


| Content-type | Opción de acceso directo | Comportamiento | 
| --- | --- | --- | 
| Ninguno El valor predeterminado de API Gateway es `application/json` | WHEN\$1NO\$1MATCH | La carga de solicitud no se transforma y se envía al backend tal como está. | 
| Ninguno El valor predeterminado de API Gateway es `application/json` | WHEN\$1NO\$1TEMPLATES | La solicitud se rechaza con una respuesta HTTP 415 Unsupported Media Type. | 
| Ninguno El valor predeterminado de API Gateway es `application/json` | NEVER | La solicitud se rechaza con una respuesta HTTP 415 Unsupported Media Type. | 
| application/json | WHEN\$1NO\$1MATCH | La carga de solicitud no se transforma y se envía al backend tal como está. | 
| application/json | WHEN\$1NO\$1TEMPLATES | La solicitud se rechaza con una respuesta HTTP 415 Unsupported Media Type. | 
| application/json | NEVER | La solicitud se rechaza con una respuesta HTTP 415 Unsupported Media Type. | 
| application/xml | WHEN\$1NO\$1MATCH | La carga de solicitud se transforma mediante la plantilla. | 
| application/xml | WHEN\$1NO\$1TEMPLATES | La carga de solicitud se transforma mediante la plantilla. | 
| application/xml | NEVER | La carga de solicitud se transforma mediante la plantilla. | 

Ejemplo 3: no se han definido plantillas de asignación en la solicitud de integración.


| Content-type | Opción de acceso directo | Comportamiento | 
| --- | --- | --- | 
| Ninguno El valor predeterminado de API Gateway es `application/json` | WHEN\$1NO\$1MATCH | La carga de solicitud no se transforma y se envía al backend tal como está. | 
| Ninguno El valor predeterminado de API Gateway es `application/json` | WHEN\$1NO\$1TEMPLATES | La carga de solicitud no se transforma y se envía al backend tal como está. | 
| Ninguno El valor predeterminado de API Gateway es `application/json` | NEVER | La solicitud se rechaza con una respuesta HTTP 415 Unsupported Media Type. | 
| application/json | WHEN\$1NO\$1MATCH | La carga de solicitud no se transforma y se envía al backend tal como está. | 
| application/json | WHEN\$1NO\$1TEMPLATES | La carga de solicitud no se transforma y se envía al backend tal como está. | 
| application/json | NEVER | La solicitud se rechaza con una respuesta HTTP 415 Unsupported Media Type. | 
| application/xml | WHEN\$1NO\$1MATCH | La carga de solicitud no se transforma y se envía al backend tal como está. | 
| application/xml | WHEN\$1NO\$1TEMPLATES | La carga de solicitud no se transforma y se envía al backend tal como está. | 
| application/xml | NEVER | La solicitud se rechaza con una respuesta HTTP 415 Unsupported Media Type. | 

# Ejemplo de plantilla de asignación adicional para las API de REST en API Gateway
<a name="example-photos"></a>

En el siguiente ejemplo se muestra una API de álbum de fotos en API Gateway que utiliza plantillas de asignación para transformar los datos de solicitud de integración y respuesta de integración. También utiliza modelos de datos para definir la carga útil de las solicitudes de métodos y las respuestas de integración. Para obtener más información acerca de los modelos de datos, consulte [Modelos de datos para las API de REST](models-mappings-models.md).

## Solicitud de método y solicitud de integración
<a name="example-photos-request"></a>

A continuación se muestra un modelo que define el cuerpo de solicitud de método. Este modelo de entrada requiere que el intermediario cargue una página de fotos y un mínimo de 10 fotos por cada página. Puede utilizar este modelo de entrada para generar un SDK o para utilizar la validación de solicitudes para la API. Durante la validación de la solicitud, si el cuerpo de solicitud de método no se adhiere a la estructura de datos del modelo, API Gateway rechaza la solicitud. 

```
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "title": "PhotosInputModel",
  "type": "object",
  "properties": {
    "photos": {
      "type": "object",
      "required" : [
      "photo"
      ],
      "properties": {
        "page": { "type": "integer" },
        "pages": { "type": "string" },
        "perpage": { "type": "integer", "minimum" : 10 },
        "total": { "type": "string" },
        "photo": {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "id": { "type": "string" },
              "owner": { "type": "string" },
              "photographer_first_name" : {"type" : "string"},
              "photographer_last_name" : {"type" : "string"},
              "secret": { "type": "string" },
              "server": { "type": "string" },
              "farm": { "type": "integer" },
              "title": { "type": "string" },
              "ispublic": { "type": "boolean" },
              "isfriend": { "type": "boolean" },
              "isfamily": { "type": "boolean" }
            }
          }
        }
      }
    }
  }
}
```

A continuación, se muestra un ejemplo de cuerpo de solicitud de método que se adhiere a la estructura de datos del modelo de datos anterior.

```
{
  "photos": {
    "page": 1,
    "pages": "1234",
    "perpage": 100,
    "total": "123398",
    "photo": [
      {
        "id": "12345678901",
        "owner": "23456789@A12",
        "photographer_first_name" : "Saanvi",
        "photographer_last_name" : "Sarkar",
        "secret": "abc123d456",
        "server": "1234",
        "farm": 1,
        "title": "Sample photo 1",
        "ispublic": true,
        "isfriend": false,
        "isfamily": false
      },
      {
        "id": "23456789012",
        "owner": "34567890@B23",
        "photographer_first_name" : "Richard",
        "photographer_last_name" : "Roe",
        "secret": "bcd234e567",
        "server": "2345",
        "farm": 2,
        "title": "Sample photo 2",
        "ispublic": true,
        "isfriend": false,
        "isfamily": false
      }
    ]
  }
}
```

En este ejemplo, si el cliente ha enviado el cuerpo de solicitud de método anterior, esta plantilla de asignación transforma la carga útil para que coincida con el formato requerido por el punto de conexión de integración.

```
#set($inputRoot = $input.path('$'))
{
  "photos": [
#foreach($elem in $inputRoot.photos.photo)
    {
      "id": "$elem.id",
      "photographedBy": "$elem.photographer_first_name $elem.photographer_last_name",
      "title": "$elem.title",
      "ispublic": $elem.ispublic,
      "isfriend": $elem.isfriend,
      "isfamily": $elem.isfamily
    }#if($foreach.hasNext),#end
		
#end
  ]
}
```

En el siguiente ejemplo se muestran los datos de salida de la transformación:

```
{
  "photos": [
    {
      "id": "12345678901",
      "photographedBy": "Saanvi Sarkar",
      "title": "Sample photo 1",
      "ispublic": true,
      "isfriend": false,
      "isfamily": false
    },		
    {
      "id": "23456789012",
      "photographedBy": "Richard Roe",
      "title": "Sample photo 2",
      "ispublic": true,
      "isfriend": false,
      "isfamily": false
    }		
  ]
}
```

Estos datos se envían a la solicitud de integración y, a continuación, al punto de conexión de integración.

## Respuesta de integración y respuesta de método
<a name="photos-example-response"></a>

A continuación, se muestra un modelo de salida de ejemplo para los datos fotográficos del punto de conexión de integración. Puede usar este modelo como modelo de respuesta de método, que es necesario al generar un SDK con establecimiento inflexible de tipos para la API. Esto provoca que el resultado se traduzca a una clase apropiada en Java u Objective-C.

```
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "title": "PhotosOutputModel",
  "type": "object",
  "properties": {
    "photos": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "id": { "type": "string" },
          "photographedBy": { "type": "string" },
          "title": { "type": "string" },
          "ispublic": { "type": "boolean" },
          "isfriend": { "type": "boolean" },
          "isfamily": { "type": "boolean" }
        }
      }
    }
  }
}
```

El punto de conexión de integración podría no responder con una respuesta que se adhiera a la estructura de datos de este modelo. Por ejemplo, la respuesta de integración podría tener el siguiente aspecto:

```
  "photos": [
    {
      "id": "12345678901",
      "photographedBy": "Saanvi Sarkar",
      "title": "Sample photo 1",
      "description": "My sample photo 1",
      "public": true,
      "friend": false,
      "family": false
    },		
    {
      "id": "23456789012",
      "photographedBy": "Richard Roe",
      "title": "Sample photo 2",
      "description": "My sample photo 1",
      "public": true,
      "friend": false,
      "family": false
    }		
  ]
}
```

El siguiente ejemplo de plantilla de asignación transforma los datos de respuesta de integración al formato esperado por la respuesta de método:

```
#set($inputRoot = $input.path('$'))
{
  "photos": [
#foreach($elem in $inputRoot.photos.photo)
    {
      "id": "$elem.id",
      "photographedBy": "$elem.photographer_first_name $elem.photographer_last_name",
      "title": "$elem.title",
      "ispublic": $elem.public,
      "isfriend": $elem.friend,
      "isfamily": $elem.family
    }#if($foreach.hasNext),#end
		
#end
  ]
}
```

En el siguiente ejemplo se muestran los datos de salida de la transformación:

```
{
  "photos": [
    {
      "id": "12345678901",
      "photographedBy": "Saanvi Sarkar",
      "title": "Sample photo 1",
      "ispublic": true,
      "isfriend": false,
      "isfamily": false
    },		
    {
      "id": "23456789012",
      "photographedBy": "Richard Roe",
      "title": "Sample photo 2",
      "ispublic": true,
      "isfriend": false,
      "isfamily": false
    }		
  ]
}
```

Estos datos se envían a la respuesta del método y luego se devuelven al cliente.

# Anulación de los parámetros de solicitud y respuesta y de los códigos de estado de la API para las API de REST en API Gateway
<a name="apigateway-override-request-response-parameters"></a>

Puede utilizar las transformaciones de plantilla de asignación para anular cualquier tipo de parámetro de solicitud, encabezado de respuesta o código de estado de respuesta. Utiliza una plantilla de asignación para hacer lo siguiente:
+ Realizar asignaciones de parámetros muchos a uno
+ Anular parámetros una vez aplicadas las asignaciones de API Gateway estándar
+ Asignar parámetros condicionalmente en función del contenido del cuerpo u otros valores de parámetro
+ Crear nuevos parámetros mediante programación
+ Anular los códigos de estado devueltos por el punto de conexión de integración

Las invalidaciones son definitivas. Una invalidación solo puede aplicarse a cada parámetro una vez. Si intenta anular el mismo parámetro varias veces, API Gateway devuelve una respuesta `5XX`. Si tiene que invalidar el mismo parámetro varias veces en la plantilla, le recomendamos crear una variable y aplicar la invalidación al final de la plantilla. La plantilla solo se aplica una vez analizada en su totalidad.

## Ejemplo 1: anular el código de estado en función del cuerpo de integración
<a name="apigateway-override-request-response-examples"></a>

En el siguiente ejemplo se utiliza la [API de ejemplo](api-gateway-create-api-from-example.md) para anular el código de estado en función del cuerpo de la respuesta de integración.

------
#### [ Consola de administración de AWS ]

**Anulación de un código de estado basado en el cuerpo de respuesta de integración**

1. Inicie sesión en la consola de API Gateway, en [https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway).

1. Seleccione **Crear API**.

1. En **API de REST**, elija **Compilación**.

1. En **Detalles de la API**, elija **API de ejemplo**.

1. Seleccione **Crear API**.

   API Gateway crea una API de tienda de mascotas de ejemplo. Para recuperar información sobre una mascota, utilice la solicitud de método de API de `GET /pets/{petId}`, donde `{petId}` es un parámetro de ruta correspondiente a un número de identificación de una mascota.

   En este ejemplo, anula el código de respuesta del método `GET` a `400` cuando se detecta una condición de error.

1. En el árbol **Recursos**, elija el método `GET` en `/{petId}`.

1. Primero, pruebe la implementación actual de la API. 

   Elija la pestaña **Prueba**. Puede que tenga que elegir el botón de flecha hacia la derecha para mostrar la pestaña.

1. En **petId**, introduzca **-1** y, a continuación, seleccione **Prueba**.

   El **Cuerpo de respuesta** indica un error de fuera de intervalo:

   ```
   {
     "errors": [
       {
         "key": "GetPetRequest.petId",
         "message": "The value is out of range."
       }
     ]
   }
   ```

   Además, la última línea bajo **Registros** termina por `Method completed with status: 200`.

   La integración se ha completado correctamente, pero se ha producido un error. Ahora, anulará el código de estado basado en el cuerpo de respuesta de integración.

1. En la pestaña **Respuesta de integración**, en **Predeterminado: respuesta**, seleccione **Editar**.

1. Elija **Plantillas de mapeo**.

1. Elija **Add mapping template (Añadir plantilla de asignación)**.

1. En **Tipo de contenido**, ingrese **application/json**.

1. En **Cuerpo de la plantilla**, introduzca lo siguiente:

   ```
   #set($inputRoot = $input.path('$'))
   $input.json("$")
   #if($inputRoot.toString().contains("error"))
   #set($context.responseOverride.status = 400)
   #end
   ```

   Esta plantilla de asignación utiliza la variable `$context.responseOverride.status` para anular el código de estado a `400` si la respuesta de integración contiene la cadena `error`.

1. Seleccione **Save**.

1. Elija la pestaña **Prueba**.

1. En **petId**, introduzca **-1**.

1. En los resultados, el **Response Body (Cuerpo de respuesta)** indica un error de fuera de intervalo:

   ```
   {
     "errors": [
       {
         "key": "GetPetRequest.petId",
         "message": "The value is out of range."
       }
     ]
   }
   ```

   Sin embargo, la última línea de **Registros** termina ahora por `Method completed with status: 400`.

------
#### [ CloudFormation ]

 En este ejemplo, utiliza la propiedad [body](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-apigateway-restapi.html#cfn-apigateway-restapi-body) para importar un archivo de definición de OpenAPI en API Gateway. 

```
AWSTemplateFormatVersion: 2010-09-09
Resources:
  Api:
    Type: 'AWS::ApiGateway::RestApi'
    Properties:
      Body: 
        openapi: 3.0.1
        info:
          title: PetStore Example 1
          description: Example pet store API.
          version: "2025-01-14T00:13:18Z"
        paths:
          /pets/{petId}:
            get:
              parameters:
                - name: petId
                  in: path
                  required: true
                  schema:
                    type: string
              responses:
                "200":
                  description: 200 response
              x-amazon-apigateway-integration:
                httpMethod: GET
                uri: http://petstore.execute-api.us-east-1.amazonaws.com/petstore/pets/{petId}
                responses:
                  default:
                    statusCode: "200"
                    responseTemplates:
                      application/json: |-
                        #set($inputRoot = $input.path('$'))
                        $input.json("$")
                        #if($inputRoot.toString().contains("error"))
                        #set($context.responseOverride.status = 400)
                        #end
                requestParameters:
                  integration.request.path.petId: method.request.path.petId
                passthroughBehavior: when_no_match
                type: http
        components:
          schemas:
            Pet:
              type: object
              properties:
                id:
                  type: integer
                type:
                  type: string
                price:
                  type: number
  ApiGatewayDeployment:
    Type: 'AWS::ApiGateway::Deployment'
    DependsOn: Api 
    Properties: 
      RestApiId: !Ref Api
  ApiGatewayDeployment20250219:
    Type: 'AWS::ApiGateway::Deployment'
    DependsOn: Api 
    Properties: 
      RestApiId: !Ref Api
  Stage:
    Type: 'AWS::ApiGateway::Stage'
    Properties:
       DeploymentId: !Ref ApiGatewayDeployment20250219
       RestApiId: !Ref Api
       StageName: prod
```

------
#### [ OpenAPI ]

La siguiente definición de OpenAPI crea el recurso `GET pets/{petId}` y anula el código de estado en función del cuerpo de integración.

```
{
  "openapi" : "3.0.1",
  "info" : {
    "title" : "PetStore Example 1",
    "description" : "Example pet store API.",
    "version" : "2025-01-14T00:13:18Z"
  },
  "paths" : {
    "/pets/{petId}" : {
      "get" : {
        "parameters" : [ {
          "name" : "petId",
          "in" : "path",
          "required" : true,
          "schema" : {
            "type" : "string"
          }
        } ],
        "responses" : {
          "200" : {
            "description" : "200 response"
          }
        },
        "x-amazon-apigateway-integration" : {
          "httpMethod" : "GET",
          "uri" : "http://petstore.execute-api.us-east-1.amazonaws.com/petstore/pets/{petId}",
          "responses" : {
            "default" : {
              "statusCode" : "200",
              "responseTemplates" : {
                "application/json" : "#set($inputRoot = $input.path('$'))\n$input.json(\"$\")\n#if($inputRoot.toString().contains(\"error\"))\n#set($context.responseOverride.status = 400)\n#end"
              }
            }
          },
          "requestParameters" : {
            "integration.request.path.petId" : "method.request.path.petId"
          },
          "passthroughBehavior" : "when_no_match",
          "type" : "http"
        }
      }
    }
  },
  "components" : {
    "schemas" : {
      "Pet" : {
        "type" : "object",
        "properties" : {
          "id" : {
            "type" : "integer"
          },
          "type" : {
            "type" : "string"
          },
          "price" : {
            "type" : "number"
          }
        }
      }
    }
  }
}
```

------

## Ejemplo 2: anular el encabezado de solicitud y crear nuevos encabezados
<a name="apigateway-override-request-response-examples-2"></a>

En el siguiente ejemplo se utiliza la [API de ejemplo](api-gateway-create-api-from-example.md) para anular el encabezado de solicitud y crear nuevos encabezados.

------
#### [ Consola de administración de AWS ]

**Anulación del encabezado de solicitud de un método mediante la creación de un nuevo encabezado**

1. Inicie sesión en la consola de API Gateway, en [https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway).

1. Elija la API de ejemplo que creó en el tutorial anterior. El nombre de la API debe ser **PetStore**.

1. En el árbol **Recursos**, elija el método `GET` en `/pet`.

1. En la pestaña **Solicitud de método**, en **Configuración de solicitud de método**, elija **Editar**.

1. Elija **Encabezados de solicitud HTTP** y, a continuación, elija **Agregar encabezado**.

1. En **Nombre**, escriba **header1**.

1. Elija **Agregar encabezado** y, a continuación, cree un segundo encabezado llamado **header2**.

1. Seleccione **Save**.

   Ahora, combina estos encabezados en un valor de encabezado mediante una plantilla de asignación.

1. En la pestaña **Solicitud de integración**, en **Configuración de la solicitud de integración**, seleccione **Editar**.

1. En **Acceso directo de cuerpo de la solicitud**, elija **Cuando no haya plantillas definidas (recomendado)**.

1. Elija **Plantillas de mapeo** y, a continuación, haga lo siguiente:

   1. Elija **Add mapping template (Añadir plantilla de asignación)**.

   1. En **Tipo de contenido**, ingrese **application/json**. 

   1. En **Cuerpo de la plantilla**, introduzca lo siguiente:

      ```
      #set($header1Override = "pets")
      #set($header3Value = "$input.params('header1')$input.params('header2')")
      $input.json("$")
      #set($context.requestOverride.header.header3 = $header3Value)
      #set($context.requestOverride.header.header1 = $header1Override)
      #set($context.requestOverride.header.multivalueheader=[$header1Override, $header3Value])
      ```

      Esta plantilla de asignación anula `header1` con la cadena `pets` y crea un encabezado de varios valores llamado `$header3Value` que combina `header1` y `header2`.

1. Seleccione **Save**.

1. Elija la pestaña **Prueba**.

1. En **Encabezados**, copie el siguiente código:

   ```
   header1:header1Val
   header2:header2Val
   ```

1. Seleccione **Test (Probar)**.

   En el cuadro **Registros**, debería ver una entrada que incluye este texto:

   ```
   Endpoint request headers: {header3=header1Valheader2Val, 
   header2=header2Val, header1=pets, x-amzn-apigateway-api-id=api-id,
   Accept=application/json, multivalueheader=pets,header1Valheader2Val}
   ```

------
#### [ CloudFormation ]

 En este ejemplo, utiliza la propiedad [body](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-apigateway-restapi.html#cfn-apigateway-restapi-body) para importar un archivo de definición de OpenAPI en API Gateway. 

```
AWSTemplateFormatVersion: 2010-09-09
Resources:
  Api:
    Type: 'AWS::ApiGateway::RestApi'
    Properties:
      Body: 
        openapi: 3.0.1
        info:
          title: PetStore Example 2
          description: Example pet store API.
          version: "2025-01-14T00:36:18Z"
        paths:
          /pets:
            get:
              parameters:
                - name: header2
                  in: header
                  schema:
                    type: string
                - name: page
                  in: query
                  schema:
                    type: string
                - name: type
                  in: query
                  schema:
                    type: string
                - name: header1
                  in: header
                  schema:
                    type: string
              responses:
                "200":
                  description: 200 response
              x-amazon-apigateway-integration:
                httpMethod: GET
                uri: http://petstore.execute-api.us-east-1.amazonaws.com/petstore/pets
                responses:
                  default:
                    statusCode: "200"
                requestParameters:
                  integration.request.header.header1: method.request.header.header1
                  integration.request.header.header2: method.request.header.header2
                  integration.request.querystring.page: method.request.querystring.page
                  integration.request.querystring.type: method.request.querystring.type
                requestTemplates:
                  application/json: |-
                    #set($header1Override = "pets")
                    #set($header3Value = "$input.params('header1')$input.params('header2')")
                    $input.json("$")
                    #set($context.requestOverride.header.header3 = $header3Value)
                    #set($context.requestOverride.header.header1 = $header1Override)
                    #set($context.requestOverride.header.multivalueheader=[$header1Override, $header3Value])
                passthroughBehavior: when_no_match
                type: http
        components:
          schemas:
            Pet:
              type: object
              properties:
                id:
                  type: integer
                type:
                  type: string
                price:
                  type: number
  ApiGatewayDeployment:
    Type: 'AWS::ApiGateway::Deployment'
    DependsOn: Api 
    Properties: 
      RestApiId: !Ref Api
  ApiGatewayDeployment20250219:
    Type: 'AWS::ApiGateway::Deployment'
    DependsOn: Api 
    Properties: 
      RestApiId: !Ref Api
  Stage:
    Type: 'AWS::ApiGateway::Stage'
    Properties:
       DeploymentId: !Ref ApiGatewayDeployment20250219
       RestApiId: !Ref Api
       StageName: prod
```

------
#### [ OpenAPI ]

 La siguiente definición de OpenAPI crea el recurso `GET pets` y anula el encabezado de solicitud y crea nuevos encabezados.

```
{
  "openapi" : "3.0.1",
  "info" : {
    "title" : "PetStore Example 2",
    "description" : "Example pet store API.",
    "version" : "2025-01-14T00:36:18Z"
  },
  "paths" : {
    "/pets" : {
      "get" : {
        "parameters" : [ {
          "name" : "header2",
          "in" : "header",
          "schema" : {
            "type" : "string"
          }
        }, {
          "name" : "page",
          "in" : "query",
          "schema" : {
            "type" : "string"
          }
        }, {
          "name" : "type",
          "in" : "query",
          "schema" : {
            "type" : "string"
          }
        }, {
          "name" : "header1",
          "in" : "header",
          "schema" : {
            "type" : "string"
          }
        } ],
        "responses" : {
          "200" : {
            "description" : "200 response"
          }
        },
        "x-amazon-apigateway-integration" : {
          "httpMethod" : "GET",
          "uri" : "http://petstore.execute-api.us-east-1.amazonaws.com/petstore/pets",
          "responses" : {
            "default" : {
              "statusCode" : "200"
            }
          },
          "requestParameters" : {
            "integration.request.header.header1" : "method.request.header.header1",
            "integration.request.header.header2" : "method.request.header.header2",
            "integration.request.querystring.page" : "method.request.querystring.page",
            "integration.request.querystring.type" : "method.request.querystring.type"
          },
          "requestTemplates" : {
            "application/json" : "#set($header1Override = \"pets\")\n#set($header3Value = \"$input.params('header1')$input.params('header2')\")\n$input.json(\"$\")\n#set($context.requestOverride.header.header3 = $header3Value)\n#set($context.requestOverride.header.header1 = $header1Override)\n#set($context.requestOverride.header.multivalueheader=[$header1Override, $header3Value])"
          },
          "passthroughBehavior" : "when_no_match",
          "type" : "http"
        }
      }
    }
  }
}
```

------

Para utilizar una anulación de plantilla de asignación, agregue una o más de las siguientes variables `$context`. Para ver una lista de variables `$context`, consulte [Variables de contexto para transformaciones de datos](api-gateway-mapping-template-reference.md#context-variable-reference).

# Tutorial: modificación de la solicitud y respuesta de integración para integraciones con servicios de AWS
<a name="set-up-data-transformations-in-api-gateway"></a>

En el siguiente tutorial se muestra cómo utilizar las transformaciones de plantilla de asignación para configurar plantillas de asignación con el fin de transformar las solicitudes y respuestas de integración mediante la consola y la CLI de AWS.

**Topics**
+ [

## Configuración de la transformación de datos en la consola de API Gateway
](#mapping-example-console)
+ [

## Configuración de la transformación de datos mediante la CLI de AWS
](#mapping-example-cli)
+ [

## Plantilla CloudFormation de transformación de datos completada
](#api-gateway-data-transformations-full-cfn-stack)

## Configuración de la transformación de datos en la consola de API Gateway
<a name="mapping-example-console"></a>

En este tutorial, creará una API y una tabla de DynamoDB incompletas con el siguiente archivo .zip [data-transformation-tutorial-console.zip](samples/data-transformation-tutorial-console.zip). Esta API incompleta tiene un recurso `/pets` con los métodos `GET` y `POST`. 
+ El método `GET` obtendrá datos del punto de conexión HTTP `http://petstore-demo-endpoint.execute-api.com/petstore/pets`. Los datos de salida se transformarán según la plantilla de mapeo en [Asignación de las transformaciones de plantillas de asignación para las API de REST en API Gateway](models-mappings.md).
+ El método `POST` permitirá al usuario `POST` información de la mascota en una tabla de Amazon DynamoDB mediante una plantilla de mapeo.

Descargue y descomprima [la plantilla de creación de aplicaciones para CloudFormation](samples/data-transformation-tutorial-console.zip). Utilizará esta plantilla para crear una tabla de DynamoDB para publicar información sobre la mascota y una API incompleta. Finalizará el resto de los pasos en la consola de API Gateway. 

**Para crear una pila de CloudFormation**

1. Abra la consola de CloudFormation en [https://console.aws.amazon.com/cloudformation](https://console.aws.amazon.com/cloudformation/).

1. Seleccione **Create stack (Crear pila)** y, a continuación, seleccione **With new resources (standard) (Con nuevos recursos [estándar])**.

1. En **Specify template (Especificar plantilla)**, elija **Upload a template file (Cargar un archivo de plantilla)**.

1. Seleccione la plantilla que ha descargado.

1. Elija **Next (Siguiente)**. 

1. En **Stack name (Nombre de pila)**, escriba **data-transformation-tutorial-console** y, a continuación, elija **Next (Siguiente)**.

1. En **Configure stack options (Configurar opciones de pila)**, elija **Next (Siguiente)**.

1. Para **Capabilities** (Capacidades), sepa que CloudFormation puede crear recursos de IAM en su cuenta.

1. Elija **Siguiente** y, a continuación, elija **Enviar**.

CloudFormation aprovisiona los recursos especificados en la plantilla. Puede tardar varios minutos en finalizar el aprovisionamiento de los recursos. Cuando el estado de la pila de CloudFormation sea **CREATE\$1COMPLETE**, estará listo para continuar con el paso siguiente.

**Para probar la respuesta de integración de `GET`**

1. En la pestaña **Recursos** de la pila CloudFormation de **data-transformation-tutorial-console**, seleccione el ID físico de su API.

1. En el panel de navegación principal, seleccione **Recursos** y, a continuación, seleccione el método **GET**. 

1. Elija la pestaña **Prueba**. Puede que tenga que elegir el botón de flecha hacia la derecha para mostrar la pestaña.

   El resultado de la prueba mostrará lo siguiente: 

   ```
   [
     {
       "id": 1,
       "type": "dog",
       "price": 249.99
     },
     {
       "id": 2,
       "type": "cat",
       "price": 124.99
     },
     {
       "id": 3,
       "type": "fish",
       "price": 0.99
     }
   ]
   ```

   Transformará este resultado según la plantilla de mapeo en [Asignación de las transformaciones de plantillas de asignación para las API de REST en API Gateway](models-mappings.md).

**Para transformar la respuesta de integración de `GET`**

1. Elija la pestaña **Respuesta de integración**.

   Actualmente, no hay plantillas de mapeo definidas, por lo que la respuesta de integración no se transformará. 

1. En **Predeterminado: respuesta**, seleccione **Editar**.

1. Elija **Plantillas de mapeo** y, a continuación, haga lo siguiente:

   1. Elija **Add mapping template (Añadir plantilla de asignación)**.

   1. En **Tipo de contenido**, ingrese **application/json**. 

   1. En **Cuerpo de la plantilla**, introduzca lo siguiente:

      ```
      #set($inputRoot = $input.path('$'))
      [
      #foreach($elem in $inputRoot)
        {
          "description" : "Item $elem.id is a $elem.type.",
          "askingPrice" : $elem.price
        }#if($foreach.hasNext),#end
      
      #end
      ]
      ```

   Seleccione **Save**.

**Para probar la respuesta de integración de `GET`**
+ Elija la pestaña **Prueba** y, a continuación, seleccione **Prueba**.

  El resultado de la prueba mostrará la respuesta transformada. 

  ```
  [
    {
      "description" : "Item 1 is a dog.",
      "askingPrice" : 249.99
    },
    {
      "description" : "Item 2 is a cat.",
      "askingPrice" : 124.99
    },
    {
      "description" : "Item 3 is a fish.",
      "askingPrice" : 0.99
    }
  ]
  ```

**Para transformar los datos de entrada del método `POST`**

1. Elija el método **POST**.

1. Elija la pestaña **Solicitud de integración** y, a continuación, en **Configuración de solicitud de integración**, elija **Editar**.

   La plantilla CloudFormation ha rellenado algunos de los campos de la solicitud de integración. 
   +  El tipo de integración es Servicio de AWS. 
   +  El Servicio de AWS es DynamoDB. 
   +  El método HTTP es `POST`. 
   +  La acción es `PutItem`. 
   +  La función de ejecución que permite a API Gateway incluir un elemento en la tabla de DynamoDB es `data-transformation-tutorial-console-APIGatewayRole`. CloudFormation ha creado este rol para permitir que API Gateway tuviera los permisos mínimos para interactuar con DynamoDB. 

    No se ha especificado el nombre de la tabla de DynamoDB. Especificará el nombre en los pasos siguientes. 

1. En **Acceso directo de cuerpo de la solicitud**, seleccione **Nunca**.

   Esto significa que la API rechazará los datos con tipos de contenido que no tengan una plantilla de mapeo.

1. Elija **Plantillas de mapeo**.

1. El **Tipo de contenido** está establecido en `application/json`. Esto significa que la API rechazará un tipo de contenido que no sea application/json. Para obtener más información sobre los comportamientos del acceso directo a la integración, consulte . [Comportamiento de solicitud de método para cargas útiles sin plantillas de asignación para las API de REST en API Gateway](integration-passthrough-behaviors.md)

1. Especifique el siguiente código en el editor de texto.

   ```
   {
       "TableName":"data-transformation-tutorial-console-ddb",
       "Item": {
           "id": {
               "N": $input.json("$.id")
           },
           "type": {
               "S": $input.json("$.type")
           },
           "price": {
               "N": $input.json("$.price")
           }
       }
   }
   ```

    Esta plantilla especifica la tabla como `data-transformation-tutorial-console-ddb` y establece los elementos como `id`, `type` y `price`. Los elementos procederán del cuerpo del método `POST`. También puede usar un modelo de datos para ayudar a crear una plantilla de mapeo. Para obtener más información, consulte [Solicitud de la validación de las API de REST en API Gateway](api-gateway-method-request-validation.md). 

1. Elija **Guardar** para guardar la plantilla de mapeo. 

**Para añadir un método y una respuesta de integración desde el método `POST`**

CloudFormation ha creado un método y una respuesta de integración en blanco. Editará esta respuesta para proporcionar más información. Para obtener más información sobre cómo editar las respuestas, consulte [Ejemplos de asignación de parámetros para las API de REST en API Gateway](request-response-data-mappings.md).

1. En la pestaña **Respuesta de integración**, en **Predeterminado: respuesta**, seleccione **Editar**.

1. Elija **Plantillas de mapeo** y, a continuación, elija **Agregar plantilla de mapeo**.

1. En **Content-type**, introduzca **application/json**.

1. En el editor de código, introduzca la siguiente plantilla de mapeo de salida para enviar un mensaje de salida:

   ```
   { "message" : "Your response was recorded at $context.requestTime" }
   ```

   Para obtener más información acerca de las variables de contexto, consulte [Variables de contexto para transformaciones de datos](api-gateway-mapping-template-reference.md#context-variable-reference).

1. Elija **Guardar** para guardar la plantilla de mapeo. 

**Probar el método `POST`**

Elija la pestaña **Prueba**. Puede que tenga que elegir el botón de flecha hacia la derecha para mostrar la pestaña.

1. En el cuerpo de la solicitud, introduzca el siguiente ejemplo.

   ```
   {
             "id": "4",
             "type" : "dog",
             "price": "321"
   }
   ```

1. Seleccione **Probar**

   El resultado debería mostrar su mensaje de éxito.

    Puede abrir la consola de DynamoDB en [https://console.aws.amazon.com/dynamodb/](https://console.aws.amazon.com/dynamodb/) para comprobar que el elemento de ejemplo esté en la tabla. 

**Para eliminar una pila de CloudFormation**

1. Abra la consola de CloudFormation en [https://console.aws.amazon.com/cloudformation](https://console.aws.amazon.com/cloudformation/).

1. Seleccione su pila de CloudFormation.

1. Elija **Delete (Eliminar)** y, a continuación, confirme su elección.

## Configuración de la transformación de datos mediante la CLI de AWS
<a name="mapping-example-cli"></a>

En este tutorial, creará una API y una tabla de DynamoDB incompletas con el siguiente archivo .zip [data-transformation-tutorial-cli.zip](samples/data-transformation-tutorial-cli.zip). Esta API incompleta tiene un recurso `/pets` con un método `GET` integrado en el punto de conexión HTTP `http://petstore-demo-endpoint.execute-api.com/petstore/pets`. Creará un método `POST` para conectarse a una tabla de DynamoDB y utilizará plantillas de mapeo para introducir datos en una tabla de DynamoDB. 
+ Transformará los datos de salida según la plantilla de mapeo en [Asignación de las transformaciones de plantillas de asignación para las API de REST en API Gateway](models-mappings.md).
+ Creará un método `POST` para permitir al usuario `POST` información de la mascota en una tabla de Amazon DynamoDB mediante una plantilla de mapeo.

**Para crear una pila de CloudFormation**

Descargue y descomprima [la plantilla de creación de aplicaciones para CloudFormation](samples/data-transformation-tutorial-cli.zip). 

Para completar el siguiente tutorial, necesita la [versión 2 de la AWS Command Line Interface (AWS CLI)](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html). 

Para comandos largos, se utiliza un carácter de escape (`\`) para dividir un comando en varias líneas.
**nota**  
En Windows, algunos comandos de la CLI de Bash que utiliza habitualmente (por ejemplo, `zip`) no son compatibles con los terminales integrados del sistema operativo. Para obtener una versión de Ubuntu y Bash integrada con Windows, [instale el subsistema de Windows para Linux](https://learn.microsoft.com/en-us/windows/wsl/install). Los comandos de la CLI de ejemplo de esta guía utilizan el formato Linux. Los comandos que incluyen documentos JSON en línea deben reformatearse si utiliza la CLI de Windows. 

1.  Utilice el siguiente comando para crear la pila CloudFormation.

   ```
   aws cloudformation create-stack --stack-name data-transformation-tutorial-cli --template-body file://data-transformation-tutorial-cli.zip --capabilities CAPABILITY_NAMED_IAM 
   ```

1. CloudFormation aprovisiona los recursos especificados en la plantilla. Puede tardar varios minutos en finalizar el aprovisionamiento de los recursos. Use el siguiente comando para ver el estado de su pila CloudFormation.

   ```
   aws cloudformation describe-stacks --stack-name data-transformation-tutorial-cli
   ```

1. Cuando el estado de su pila CloudFormation sea `StackStatus: "CREATE_COMPLETE"`, utilice el siguiente comando para recuperar los valores de salida relevantes para los pasos futuros.

   ```
    aws cloudformation describe-stacks --stack-name data-transformation-tutorial-cli --query "Stacks[*].Outputs[*].{OutputKey: OutputKey, OutputValue: OutputValue, Description: Description}"
   ```

   A continuación se muestran los valores de salida:
   + ApiRole, que es el nombre del rol que permite a API Gateway incluir elementos en la tabla de DynamoDB. En este tutorial, el nombre de rol es `data-transformation-tutorial-cli-APIGatewayRole-ABCDEFG`.
   + DDBTableName, que es el nombre de la tabla de DynamoDB. En este tutorial, el nombre de la tabla es `data-transformation-tutorial-cli-ddb`.
   + ResourceId, que es el identificador del recurso de las mascotas donde están expuestos los métodos `GET` y `POST`. Para este tutorial, el ID del recurso es `efg456`.
   + ApiID, que es el identificador de la API. Para este tutorial, el ID de la API es `abc123`.

**Para probar el método `GET` antes de la transformación de datos**
+ Utilice el siguiente comando para probar el método `GET`. 

  ```
  aws apigateway test-invoke-method --rest-api-id abc123 \
            --resource-id efg456 \
            --http-method GET
  ```

  El resultado de la prueba mostrará lo siguiente.

  ```
  [
    {
      "id": 1,
      "type": "dog",
      "price": 249.99
    },
    {
      "id": 2,
      "type": "cat",
      "price": 124.99
    },
    {
      "id": 3,
      "type": "fish",
      "price": 0.99
    }
  ]
  ```

  Transformará este resultado según la plantilla de mapeo en [Asignación de las transformaciones de plantillas de asignación para las API de REST en API Gateway](models-mappings.md).

**Para transformar la respuesta de integración de `GET`**
+ Use el siguiente comando para actualizar la respuesta de integración del método `GET`. Reemplace *rest-api-id* y *resource-id* con sus valores.

  Utilice el siguiente comando para crear la respuesta de integración.

  ```
  aws apigateway put-integration-response --rest-api-id abc123 \
    --resource-id efg456 \
    --http-method GET \
    --status-code 200 \
    --selection-pattern "" \
    --response-templates '{"application/json": "#set($inputRoot = $input.path(\"$\"))\n[\n#foreach($elem in $inputRoot)\n {\n  \"description\": \"Item $elem.id is a $elem.type\",\n  \"askingPrice\": \"$elem.price\"\n }#if($foreach.hasNext),#end\n\n#end\n]"}'
  ```

**Para probar el método `GET`**
+ Utilice el siguiente comando para probar el método `GET`.

  ```
  aws apigateway test-invoke-method --rest-api-id abc123 \
    --resource-id efg456 \
    --http-method GET \
  ```

  El resultado de la prueba mostrará la respuesta transformada. 

  ```
  [
    {
      "description" : "Item 1 is a dog.",
      "askingPrice" : 249.99
    },
    {
      "description" : "Item 2 is a cat.",
      "askingPrice" : 124.99
    },
    {
      "description" : "Item 3 is a fish.",
      "askingPrice" : 0.99
    }
  ]
  ```

**Para crear un método `POST`**

1. Use el siguiente comando para crear un método nuevo en el recurso `/pets`.

   ```
   aws apigateway put-method --rest-api-id abc123 \
     --resource-id efg456 \
     --http-method POST \
     --authorization-type "NONE" \
   ```

   Este método le permitirá enviar información de mascotas a la tabla de DynamoDB que creó en la pila CloudFormation.

1.  Utilice el siguiente comando para una integración Servicio de AWS en el método `POST`.

   ```
   aws apigateway put-integration --rest-api-id abc123 \
     --resource-id efg456 \
     --http-method POST \
     --type AWS \
     --integration-http-method POST \
     --uri "arn:aws:apigateway:us-east-2:dynamodb:action/PutItem" \
     --credentials arn:aws:iam::111122223333:role/data-transformation-tutorial-cli-APIGatewayRole-ABCDEFG \
     --request-templates '{"application/json":"{\"TableName\":\"data-transformation-tutorial-cli-ddb\",\"Item\":{\"id\":{\"N\":$input.json(\"$.id\")},\"type\":{\"S\":$input.json(\"$.type\")},\"price\":{\"N\":$input.json(\"$.price\")} }}"}'
   ```

1.  Utilice el siguiente comando para crear una respuesta de método para una llamada correcta del método `POST`. 

   ```
   aws apigateway put-method-response --rest-api-id abc123 \
     --resource-id efg456 \
     --http-method POST \
     --status-code 200
   ```

1. Utilice el siguiente comando para crear una respuesta de integración para una llamada correcta del método `POST`.

   ```
   aws apigateway put-integration-response --rest-api-id abc123 \
     --resource-id efg456 \
     --http-method POST \
     --status-code 200 \
     --selection-pattern "" \
     --response-templates '{"application/json": "{\"message\": \"Your response was recorded at $context.requestTime\"}"}'
   ```

**Para probar el método `POST`**
+ Utilice el siguiente comando para probar el método `POST`.

  ```
  aws apigateway test-invoke-method --rest-api-id abc123 \
    --resource-id efg456 \
    --http-method POST \
    --body '{\"id\": \"4\", \"type\": \"dog\", \"price\": \"321\"}'
  ```

  El resultado mostrará el mensaje correcto.

**Para eliminar una pila de CloudFormation**
+ Use el siguiente comando para eliminar los recursos CloudFormation.

  ```
  aws cloudformation delete-stack  --stack-name data-transformation-tutorial-cli
  ```

## Plantilla CloudFormation de transformación de datos completada
<a name="api-gateway-data-transformations-full-cfn-stack"></a>

El siguiente ejemplo es una plantilla CloudFormation completada, que crea una API y una tabla de DynamoDB con un recurso `/pets` con los métodos `GET` y `POST`. 
+ El método `GET` obtendrá datos del punto de conexión HTTP `http://petstore-demo-endpoint.execute-api.com/petstore/pets`. Los datos de salida se transformarán según la plantilla de mapeo en [Asignación de las transformaciones de plantillas de asignación para las API de REST en API Gateway](models-mappings.md).
+ El método `POST` permitirá al usuario `POST` información de la mascota en una tabla de DynamoDB mediante una plantilla de mapeo.

### Plantilla de CloudFormation de ejemplo
<a name="mapping-template-cfn-example"></a>

```
AWSTemplateFormatVersion: 2010-09-09
Description: A completed Amazon API Gateway REST API that uses non-proxy integration to POST to an Amazon DynamoDB table and non-proxy integration to GET transformed pets data.
Parameters:
  StageName:
    Type: String
    Default: v1
    Description: Name of API stage.
Resources:
  DynamoDBTable:
    Type: 'AWS::DynamoDB::Table'
    Properties:
      TableName: !Sub data-transformation-tutorial-complete
      AttributeDefinitions:
        - AttributeName: id
          AttributeType: N
      KeySchema:
        - AttributeName: id
          KeyType: HASH
      ProvisionedThroughput:
        ReadCapacityUnits: 5
        WriteCapacityUnits: 5
  APIGatewayRole:
    Type: 'AWS::IAM::Role'
    Properties:
      AssumeRolePolicyDocument:
        Version: 2012-10-17		 	 	 
        Statement:
          - Action:
              - 'sts:AssumeRole'
            Effect: Allow
            Principal:
              Service:
                - apigateway.amazonaws.com
      Policies:
        - PolicyName: APIGatewayDynamoDBPolicy
          PolicyDocument:
            Version: 2012-10-17		 	 	 
            Statement:
              - Effect: Allow
                Action:
                  - 'dynamodb:PutItem'
                Resource: !GetAtt DynamoDBTable.Arn
  Api:
    Type: 'AWS::ApiGateway::RestApi'
    Properties:
      Name: data-transformation-complete-api
      ApiKeySourceType: HEADER
  PetsResource:
    Type: 'AWS::ApiGateway::Resource'
    Properties:
      RestApiId: !Ref Api
      ParentId: !GetAtt Api.RootResourceId
      PathPart: 'pets'
  PetsMethodGet:
    Type: 'AWS::ApiGateway::Method'
    Properties:
      RestApiId: !Ref Api
      ResourceId: !Ref PetsResource
      HttpMethod: GET
      ApiKeyRequired: false
      AuthorizationType: NONE
      Integration:
        Type: HTTP
        Credentials: !GetAtt APIGatewayRole.Arn
        IntegrationHttpMethod: GET
        Uri: http://petstore-demo-endpoint.execute-api.com/petstore/pets/
        PassthroughBehavior: WHEN_NO_TEMPLATES
        IntegrationResponses:
          - StatusCode: '200'
            ResponseTemplates:
              application/json: "#set($inputRoot = $input.path(\"$\"))\n[\n#foreach($elem in $inputRoot)\n {\n  \"description\": \"Item $elem.id is a $elem.type\",\n  \"askingPrice\": \"$elem.price\"\n }#if($foreach.hasNext),#end\n\n#end\n]"
      MethodResponses:
        - StatusCode: '200'
  PetsMethodPost:
    Type: 'AWS::ApiGateway::Method'
    Properties:
      RestApiId: !Ref Api
      ResourceId: !Ref PetsResource
      HttpMethod: POST
      ApiKeyRequired: false
      AuthorizationType: NONE
      Integration:
        Type: AWS
        Credentials: !GetAtt APIGatewayRole.Arn
        IntegrationHttpMethod: POST
        Uri: arn:aws:apigateway:us-west-1:dynamodb:action/PutItem
        PassthroughBehavior: NEVER
        RequestTemplates: 
          application/json: "{\"TableName\":\"data-transformation-tutorial-complete\",\"Item\":{\"id\":{\"N\":$input.json(\"$.id\")},\"type\":{\"S\":$input.json(\"$.type\")},\"price\":{\"N\":$input.json(\"$.price\")} }}"
        IntegrationResponses:
          - StatusCode: 200
            ResponseTemplates:
              application/json: "{\"message\": \"Your response was recorded at $context.requestTime\"}"
      MethodResponses:
        - StatusCode: '200'

  ApiDeployment:
    Type: 'AWS::ApiGateway::Deployment'
    DependsOn:
      - PetsMethodGet
    Properties:
      RestApiId: !Ref Api
      StageName: !Sub '${StageName}'
Outputs:
  ApiId:
    Description: API ID for CLI commands
    Value: !Ref Api
  ResourceId:
    Description: /pets resource ID for CLI commands
    Value: !Ref PetsResource
  ApiRole:
    Description: Role ID to allow API Gateway to put and scan items in DynamoDB table
    Value: !Ref APIGatewayRole
  DDBTableName:
    Description: DynamoDB table name
    Value: !Ref DynamoDBTable
```

# Ejemplos que utilizan variables para las transformaciones de plantilla de asignación para API Gateway
<a name="api-gateway-mapping-variable-examples"></a>

En los siguientes ejemplos se muestra cómo utilizar las variables `$context`, `input` y `util` en las plantillas de asignación. Puede utilizar una integración simulada o una integración sin proxy de Lambda que devuelva el evento de entrada a API Gateway. Para obtener una lista de todas las variables admitidas para las transformaciones de datos, consulte [Variables para transformaciones de datos para API Gateway](api-gateway-mapping-template-reference.md).

## Ejemplo 1: pase de múltiples variables `$context` al punto de conexión de integración
<a name="context-variables-template-example"></a>

El siguiente ejemplo muestra una plantilla de asignación que mapea variables `$context` de entrada a las variables de backend con nombres ligeramente diferentes en una carga de la solicitud de integración:

```
{
    "stage" : "$context.stage",
    "request_id" : "$context.requestId",
    "api_id" : "$context.apiId",
    "resource_path" : "$context.resourcePath",
    "resource_id" : "$context.resourceId",
    "http_method" : "$context.httpMethod",
    "source_ip" : "$context.identity.sourceIp",
    "user-agent" : "$context.identity.userAgent",
    "account_id" : "$context.identity.accountId",
    "api_key" : "$context.identity.apiKey",
    "caller" : "$context.identity.caller",
    "user" : "$context.identity.user",
    "user_arn" : "$context.identity.userArn"
}
```

La salida de esta plantilla de asignación debe tener el siguiente aspecto:

```
{
  stage: 'prod',
  request_id: 'abcdefg-000-000-0000-abcdefg',
  api_id: 'abcd1234',
  resource_path: '/',
  resource_id: 'efg567',
  http_method: 'GET',
  source_ip: '192.0.2.1',
  user-agent: 'curl/7.84.0',
  account_id: '111122223333',
  api_key: 'MyTestKey',
  caller: 'ABCD-0000-12345',
  user: 'ABCD-0000-12345',
  user_arn: 'arn:aws:sts::111122223333:assumed-role/Admin/carlos-salazar'
}
```

Una de las variables es una clave de API. En este ejemplo se supone que el método requiere una clave de API.

## Ejemplo 2: pase de todos los parámetros de solicitud al punto de conexión de integración a través de una carga útil JSON
<a name="input-examples-mapping-templates"></a>

El siguiente ejemplo pasa todos los parámetros de solicitud, como los parámetros `path`, `querystring` y `header`, a través del punto de conexión de integración mediante una carga útil de JSON:

```
#set($allParams = $input.params())
{
  "params" : {
    #foreach($type in $allParams.keySet())
    #set($params = $allParams.get($type))
    "$type" : {
      #foreach($paramName in $params.keySet())
      "$paramName" : "$util.escapeJavaScript($params.get($paramName))"
      #if($foreach.hasNext),#end
      #end
    }
    #if($foreach.hasNext),#end
    #end
  }
}
```

Si una solicitud tiene los siguientes parámetros de entrada:
+ Un parámetro de ruta denominado `myparam`
+ Parámetros de cadenas de consulta `querystring1=value1,value2`
+ Encabezados `"header1" : "value1"`.

La salida de esta plantilla de asignación debe tener el siguiente aspecto:

```
{"params":{"path":{"example2":"myparamm"},"querystring":{"querystring1":"value1,value2"},"header":{"header1":"value1"}}}
```

## Ejemplo 3: pase de una subsección de una solicitud de método al punto de conexión de integración
<a name="input-example-json-mapping-template"></a>

 En el siguiente ejemplo se utiliza el parámetro de entrada `name` para recuperar solo el parámetro `name` y el parámetro de entrada `input.json('$')` para recuperar todo el cuerpo de la solicitud de método:

```
{
    "name" : "$input.params('name')",
    "body" : $input.json('$') 
}
```

Para una solicitud que incluye los parámetros de cadena de consulta `name=Bella&type=dog` y el cuerpo siguiente:

```
{
    "Price" : "249.99",
    "Age": "6"
}
```

La salida de esta plantilla de asignación debe tener el siguiente aspecto:

```
{
    "name" : "Bella",
    "body" : {"Price":"249.99","Age":"6"}
}
```

Esta plantilla de asignación elimina el parámetro de cadena de consulta `type=dog`.

 Si la entrada JSON contiene caracteres sin escape que no puede analizar JavaScript, es posible que API Gateway devuelva una respuesta 400. Aplique `$util.escapeJavaScript($input.json('$'))` para asegurarse de que la entrada JSON se pueda analizar correctamente. 

El ejemplo anterior con `$util.escapeJavaScript($input.json('$'))` se aplica de la siguiente manera:

```
{
    "name" : "$input.params('name')",
    "body" : "$util.escapeJavaScript($input.json('$'))"
}
```

En este caso, la salida de esta plantilla de asignación debe tener el siguiente aspecto:

```
{
    "name" : "Bella",
    "body": {"Price":"249.99","Age":"6"}
}
```

## Ejemplo 4: uso de una expresión JSONPath para pasar una subsección de una solicitud de método al punto de conexión de integración
<a name="input-example-inputs-mapping-template"></a>

En el siguiente ejemplo se utilizan expresiones JSONPath para recuperar solo el parámetro de entrada `name` y el valor de `Age` del cuerpo de solicitud:

```
{
    "name" : "$input.params('name')",
    "body" : $input.json('$.Age')  
}
```

Para una solicitud que incluye los parámetros de cadena de consulta `name=Bella&type=dog` y el cuerpo siguiente:

```
{
    "Price" : "249.99",
    "Age": "6"
}
```

La salida de esta plantilla de asignación debe tener el siguiente aspecto:

```
{
    "name" : "Bella",
    "body" : "6"
}
```

Esta plantilla de asignación elimina el parámetro de cadena de consulta `type=dog` y el campo `Price` del cuerpo.

 Si una carga de solicitud de método contiene caracteres sin escape que no puede analizar JavaScript, es posible que API Gateway devuelva una respuesta `400`. Aplique `$util.escapeJavaScript()` para asegurarse de que la entrada JSON se pueda analizar correctamente.

El ejemplo anterior con `$util.escapeJavaScript($input.json('$.Age'))` se aplica de la siguiente manera:

```
{
    "name" : "$input.params('name')",
    "body" : "$util.escapeJavaScript($input.json('$.Age'))" 
}
```

En este caso, la salida de esta plantilla de asignación debe tener el siguiente aspecto:

```
{
    "name" : "Bella",
    "body": "\"6\""
}
```

## Ejemplo 5: uso de una expresión JSONPath para pasar información sobre una solicitud de método al punto de conexión de integración
<a name="input-example-request-and-response"></a>

En el siguiente ejemplo se utilizan `$input.params()`, `$input.path()` y `$input.json()` para enviar información sobre una solicitud de método al punto de conexión de integración. Esta plantilla de asignación utiliza el método `size()` para proporcionar el número de elementos de una lista.

```
{
    "id" : "$input.params('id')",
    "count" : "$input.path('$.things').size()",
    "things" : $input.json('$.things')
}
```

Para una solicitud que incluye el parámetros de ruta `123` y el cuerpo siguiente:

```
{
      "things": {
            "1": {},
            "2": {},
            "3": {}
      }
}
```

La salida de esta plantilla de asignación debe tener el siguiente aspecto:

```
{"id":"123","count":"3","things":{"1":{},"2":{},"3":{}}}
```

 Si una carga de solicitud de método contiene caracteres sin escape que no puede analizar JavaScript, es posible que API Gateway devuelva una respuesta `400`. Aplique `$util.escapeJavaScript()` para asegurarse de que la entrada JSON se pueda analizar correctamente.

El ejemplo anterior con `$util.escapeJavaScript($input.json('$.things'))` se aplica de la siguiente manera:

```
{
     "id" : "$input.params('id')",
     "count" : "$input.path('$.things').size()",
     "things" : "$util.escapeJavaScript($input.json('$.things'))"
}
```

La salida de esta plantilla de asignación debe tener el siguiente aspecto:

```
{"id":"123","count":"3","things":"{\"1\":{},\"2\":{},\"3\":{}}"}
```