

# Tutorial: Creación de una API de REST de calculadora con dos integraciones de servicios de AWS y una integración de Lambda sin proxy
<a name="integrating-api-with-aws-services-lambda"></a>

El [Tutorial: Creación de una API de REST con una integración no de proxy de Lambda](getting-started-lambda-non-proxy-integration.md) solamente utiliza la integración de `Lambda Function`. La integración de `Lambda Function` es un caso especial del tipo de integración de `AWS Service` que configura por usted la mayor parte de la integración; por ejemplo, la incorporación automática de los permisos basados en recursos necesarios para invocar la función de Lambda. Aquí, dos de las tres integraciones usan integración de `AWS Service`. En este tipo de integración, tiene más control, pero tendrá que realizar manualmente tareas como la creación y especificación de un rol de IAM que contenga los permisos adecuados.



En este tutorial, creará una función `Calc` de Lambda que implementa operaciones aritméticas básicas, aceptando y devolviendo entradas y salidas con formato JSON. A continuación, creará una API REST y la integrará con la función de Lambda de la siguiente forma:

1. Exponiendo un método de `GET` en el recurso `/calc` para invocar la función de Lambda, proporcionando la entrada como parámetros de cadena de consulta. (Integración de `AWS Service`)

1. Exponiendo un método de `POST` en el recurso `/calc` para invocar la función de Lambda, proporcionando la entrada en la carga de la solicitud del método. (Integración de `AWS Service`)

1. Exponiendo un método `GET` en recursos `/calc/{operand1}/{operand2}/{operator}` anidados para invocar la función de Lambda, proporcionando la entrada como parámetros de ruta. (Integración de `Lambda Function`)

Además de probar con este tutorial, sugerimos que estudie el [archivo de definición de OpenAPI](api-as-lambda-proxy-export-swagger-with-extensions.md) para la API de `Calc`, que puede importar a API Gateway siguiendo las instrucciones de [Desarrollo de API de REST mediante OpenAPI en API Gateway](api-gateway-import-api.md).

**Topics**
+ [Crear un rol de IAM asumible](#api-as-lambda-proxy-setup-iam-role-policies)
+ [Creación de una función `Calc` de Lambda](#api-as-lambda-proxy-create-lambda-function)
+ [Probar la función `Calc` de Lambda](#api-as-lambda-proxy-test-lambda-function-)
+ [Cree una API de `Calc`](#api-as-lambda-proxy-create-api-resources)
+ [Integración 1: Crear un método `GET` con parámetros de consulta para llamar a la función de Lambda](#api-as-lambda-proxy-expose-get-method-with-query-strings-to-call-lambda-function)
+ [Integración 2: Crear un método `POST` con una carga JSON para llamar a la función de Lambda](#api-as-lambda-proxy-expose-post-method-with-json-body-to-call-lambda-function)
+ [Integración 3: Crear un método `GET` con parámetros de ruta para llamar a la función de Lambda](#api-as-lambda-proxy-expose-get-method-with-path-parameters-to-call-lambda-function)
+ [Definiciones de OpenAPI de una API de ejemplo integrada con una función de Lambda](api-as-lambda-proxy-export-swagger-with-extensions.md)

## Crear un rol de IAM asumible
<a name="api-as-lambda-proxy-setup-iam-role-policies"></a>

Para que su API invoque su función `Calc` de Lambda, necesitará tener un rol de IAM asumible por API Gateway, que es un rol de IAM con la siguiente relación de confianza:

------
#### [ JSON ]

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Sid": "",
      "Effect": "Allow",
      "Principal": {
        "Service": "apigateway.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
```

------

El rol que cree tendrá que tener el permiso [InvokeFunction](https://docs.aws.amazon.com/lambda/latest/api/API_Invoke.html) de Lambda. De lo contrario, el intermediario de la API recibirá una respuesta `500 Internal Server Error`. Para dar al rol este permiso, asociará la siguiente política de IAM:

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "lambda:InvokeFunction",
            "Resource": "*"
        }
    ]
}
```

------

A continuación, se explica cómo realizar todo esto:

**Crear un rol de IAM asumible por API Gateway**

1. Inicie sesión en la consola de IAM.

1. Elija **Roles**.

1. Elija **Create Role**.

1. En **Seleccionar el tipo de entidad de confianza**, elija **Servicio de AWS**.

1. En **Choose the service that will use this role (Elegir el servicio que usará este rol)**, elija **Lambda**.

1. Elija **Next: Permissions** (Siguiente: permisos).

1. Elija **Create Policy (Crear política)**.

   Se abrirá una nueva ventana de consola **Create Policy (Crear política)**. En esa ventana, haga lo siguiente:

   1. En la pestaña **JSON**, reemplace la política existente por la siguiente:

------
#### [ JSON ]

****  

      ```
      {
          "Version":"2012-10-17",		 	 	 
          "Statement": [
              {
                  "Effect": "Allow",
                  "Action": "lambda:InvokeFunction",
                  "Resource": "*"
              }
          ]
      }
      ```

------

   1. Elija **Review policy (Revisar política)**.

   1. En **Review Policy (Revisar política)** haga lo siguiente:

      1. En **Nombre**, escriba un nombre, como **lambda\$1execute**.

      1. Elija **Create Policy (Crear política)**.

1. En la ventana de consola **Create Role (Crear rol)** original, haga lo siguiente:

   1. En **Attach permissions policies (Asociar políticas de permisos)**, elija la política **lambda\$1execute** de la lista desplegable.

      Si no ve su política en la lista, haga clic en el botón Refresh (Actualizar) en la parte superior de la lista. (¡No actualice la página del navegador\$1)

   1. Elija **Next: Tags (Siguiente: Etiquetas)**.

   1. Elija **Next: Review**.

   1. En **Role name (Nombre de rol)**, escriba un nombre como **lambda\$1invoke\$1function\$1assume\$1apigw\$1role**.

   1. Elija **Create role (Crear rol)**.

1. Elija el rol **lambda\$1invoke\$1function\$1assume\$1apigw\$1role** de la lista de roles.

1. Seleccione la pestaña **Trust Relationships (Relaciones de confianza)**.

1. Elija **Edit trust relationship (Editar relación de confianza)**.

1. Reemplace la política existente por la siguiente:

------
#### [ JSON ]

****  

   ```
   {
     "Version":"2012-10-17",		 	 	 
     "Statement": [
       {
         "Sid": "",
         "Effect": "Allow",
         "Principal": {
           "Service": [
             "lambda.amazonaws.com",
             "apigateway.amazonaws.com"
           ]
         },
         "Action": "sts:AssumeRole"
       }
     ]
   }
   ```

------

1. Elija **Update Trust Policy**.

1. Anote el ARN del rol que acaba de crear. Lo necesitará más adelante.

## Creación de una función `Calc` de Lambda
<a name="api-as-lambda-proxy-create-lambda-function"></a>

A continuación, creará una función de Lambda con la consola de Lambda.

1. En la consola de Lambda, elija **Create function (Crear función)**.

1. Elija **Author from Scratch (Crear desde cero)**.

1. En **Name (Nombre)** escriba **Calc**.

1. En **Tiempo de ejecución**, elija el último tiempo de ejecución de **Node.js** o **Python** compatible.

1. Para todas las demás opciones, utilice la configuración predeterminada.

1. Seleccione **Creación de función**.

1.  Copie la siguiente función de Lambda en el tiempo de ejecución de su preferencia y péguela en el editor de código en la consola de Lambda. 

------
#### [ Node.js ]

   ```
   export const handler = async function (event, context) {
     console.log("Received event:", JSON.stringify(event));
   
     if (
       event.a === undefined ||
       event.b === undefined ||
       event.op === undefined
     ) {
       return "400 Invalid Input";
     }
   
     const res = {};
     res.a = Number(event.a);
     res.b = Number(event.b);
     res.op = event.op;
     if (isNaN(event.a) || isNaN(event.b)) {
       return "400 Invalid Operand";
     }
     switch (event.op) {
       case "+":
       case "add":
         res.c = res.a + res.b;
         break;
       case "-":
       case "sub":
         res.c = res.a - res.b;
         break;
       case "*":
       case "mul":
         res.c = res.a * res.b;
         break;
       case "/":
       case "div":
         if (res.b == 0) {
           return "400 Divide by Zero";
         } else {
           res.c = res.a / res.b;
         }
         break;
       default:
         return "400 Invalid Operator";
     }
   
     return res;
   };
   ```

------
#### [ Python ]

   ```
   import json
   
   
   def lambda_handler(event, context):
       print(event)
   
       try:
           (event['a']) and (event['b']) and (event['op'])
       except KeyError:
           return '400 Invalid Input'
   
       try:
           res = {
               "a": float(
                   event['a']), "b": float(
                   event['b']), "op": event['op']}
       except ValueError:
           return '400 Invalid Operand'
   
       if event['op'] == '+':
           res['c'] = res['a'] + res['b']
       elif event['op'] == '-':
           res['c'] = res['a'] - res['b']
       elif event['op'] == '*':
           res['c'] = res['a'] * res['b']
       elif event['op'] == '/':
           if res['b'] == 0:
               return '400 Divide by Zero'
           else:
               res['c'] = res['a'] / res['b']
       else:
           return '400 Invalid Operator'
   
       return res
   ```

------

1. Bajo Execution role (Rol de ejecución) elija **Choose an existing role (Elegir un rol existente)**.

1. Escriba el ARN del rol para el rol **lambda\$1invoke\$1function\$1assume\$1apigw\$1role** que creó anteriormente.

1. Elija **Deploy (Implementar)**.

 Esta función requiere dos operandos (`a` y `b`) y un operador (`op`) del parámetro de entrada `event`. La entrada es un objeto JSON con el siguiente formato: 

```
{
  "a": "Number" | "String",
  "b": "Number" | "String",
  "op": "String"
}
```

Esta función devuelve el resultado calculado (`c`) y la entrada. Si se trata de una entrada no válida, la función devuelve el valor null o la cadena "Invalid op" como resultado. La salida tiene el siguiente formato JSON: 

```
{
  "a": "Number",
  "b": "Number",
  "op": "String",
  "c": "Number" | "String"
}
```

Debe probar la función en la consola de Lambda antes de integrarla con la API en el siguiente paso. 

## Probar la función `Calc` de Lambda
<a name="api-as-lambda-proxy-test-lambda-function-"></a>

Indicamos aquí como probar la función `Calc` en la consola de Lambda.

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

1. Para el nombre del evento de prueba, escriba **calc2plus5**.

1. Sustituya la definición del evento de prueba por lo siguiente:

   ```
   {
     "a": "2",
     "b": "5",
     "op": "+"
   }
   ```

1. Seleccione **Save**.

1. Seleccione **Probar**

1. Expanda **Execution result: succeeded (Resultado de la ejecución: correcta)**. Debería ver lo siguiente:

   ```
   {
     "a": 2,
     "b": 5,
     "op": "+",
     "c": 7
   }
   ```

## Cree una API de `Calc`
<a name="api-as-lambda-proxy-create-api-resources"></a>

El procedimiento siguiente describe cómo crear una API para la función `Calc` de Lambda que acaba de crear. En las siguientes secciones, añadirá recursos y métodos.

**Para crear un API**

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

1. Si es la primera vez que utiliza API Gateway, verá una página en la que aparecen las características del servicio. En **REST API**, elija **Build (Compilación)**. Cuando aparezca el menú emergente **Create Example API (Crear API de ejemplo)**, elija **OK (Aceptar)**.

   Si esta no es la primera vez que utiliza API Gateway, elija **Create API (Crear API)**. En **REST API**, elija **Build (Compilación)**.

1.  En **API name (Nombre de la API)**, escriba**LambdaCalc**.

1. (Opcional) En **Description (Descripción)**, introduzca una descripción.

1. Mantenga **Tipo de punto de conexión de la API** establecido en **Regional**.

1. En **Tipo de dirección IP**, seleccione **IPv4**.

1. Seleccione **Create API (Crear API)**.

## Integración 1: Crear un método `GET` con parámetros de consulta para llamar a la función de Lambda
<a name="api-as-lambda-proxy-expose-get-method-with-query-strings-to-call-lambda-function"></a>

Mediante la creación de un método `GET` que pasa los parámetros de cadenas de consulta a la función de Lambda, habilita la API que se va a invocar desde un navegador. Este método puede ser útil, en especial para las API que permiten acceso abierto.

Después de crear una API, se crea un recurso. Normalmente, los recursos de la API están organizados en un árbol de recursos de acuerdo con la lógica de la aplicación. Para este paso, debe crear un recurso **/calc**. 

**Para crear un recurso **/calc****

1. Elija **Crear recurso**.

1. Mantenga **Recurso proxy** desactivado. 

1. Mantenga **Ruta del recurso** en `/`.

1. En **Nombre del recurso**, escriba **calc**.

1. Mantenga desactivado **CORS (uso compartido de recursos entre orígenes)**.

1. Elija **Crear recurso**.

Mediante la creación de un método `GET` que pasa los parámetros de cadenas de consulta a la función de Lambda, habilita la API que se va a invocar desde un navegador. Este método puede ser útil, en especial para las API que permiten acceso abierto.

En este método, Lambda requiere que se use la solicitud `POST` para invocar cualquier función de Lambda. Este ejemplo muestra que el método HTTP en una solicitud de método del frontend puede diferir de la solicitud de integración en el backend.

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

1. Seleccione el recurso **calc** y, a continuación, elija **Crear método**.

1. En **Tipo de método**, seleccione **GET**.

1. En **Tipo de integración**, seleccione **Servicio de AWS**.

1. En **Región de AWS**, seleccione la Región de AWS donde creó la función de Lambda.

1. En **Servicio de AWS**, seleccione **Lambda**.

1. Deje **Subdominio de AWS** en blanco.

1. En **Método HTTP**, seleccione **POST**.

1. En **Tipo de acción**, elija **Usar sustitución de ruta**. Esta opción nos permite especificar el ARN de la acción [Invoke](https://docs.aws.amazon.com/lambda/latest/dg/API_Invoke.html) para ejecutar nuestra función `Calc`. 

1. En **Sustitución de ruta**, escriba **2015-03-31/functions/arn:aws:lambda:*us-east-2*:*account-id*:function:Calc/invocations**. En ** *account-id***, introduzca su identificador de Cuenta de AWS. En ***us-east-2***, introduzca la Región de AWS donde creó la función de Lambda. 

1. En **Rol de ejecución**, escriba el ARN del rol para **lambda\$1invoke\$1function\$1assume\$1apigw\$1role**.

1. No cambie la configuración de **Caché de credenciales** ni **Tiempo de espera predeterminado**.

1. Elija **Configuración de solicitud de método**.

1. En **Validador de solicitud**, seleccione **Validar parámetros de cadena de consulta y encabezados**.

   Esta configuración hará que se devuelva un mensaje de error si el cliente no especifica los parámetros requeridos.

1. Elija **Parámetros de cadenas de consulta de URL**.

   Ahora, debe configurar los parámetros de cadena de consulta para el método **GET** en el recurso **/calc** para que pueda recibir la entrada en nombre de la función de Lambda del backend.

   Para crear parámetros de cadena de consulta, haga lo siguiente:

   1. Elija **Añadir cadena de consulta**.

   1. En **Nombre**, escriba **operand1**.

   1. Active la opción **Obligatorio**.

   1. Mantenga **Almacenamiento en caché** desactivado.

   Repita los mismos pasos y cree una cadena de consulta llamada **operand2** y una cadena de consulta llamada **operator**.

1. Elija **Crear método**.

Ahora, vamos a crear una plantilla de mapeo para convertir las cadenas de consulta proporcionadas por el cliente en la carga de la solicitud de integración, tal y como requiere la función `Calc`. Esta plantilla mapea los tres parámetros de cadena de consulta declarados en **Solicitud de método** en los valores de propiedad designados del objeto JSON como entrada a la función de Lambda del backend. El objeto JSON transformado se incluirá como la carga de la solicitud de integración. 

**Para mapear los parámetros de entrada a la solicitud de integració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**.

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 el siguiente código:

   ```
   {
       "a":  "$input.params('operand1')",
       "b":  "$input.params('operand2')", 
       "op": "$input.params('operator')"   
   }
   ```

1. Seleccione **Save**.

Ahora puede probar el método `GET` para verificar que se ha configurado correctamente para invocar la función de Lambda.

**Para probar 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.

1. En **Cadenas de consulta**, escriba **operand1=2&operand2=3&operator=\$1**.

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

   El resultado debe ser parecido al siguiente:  
![\[Crear una API en API Gateway como proxy de Lambda\]](http://docs.aws.amazon.com/es_es/apigateway/latest/developerguide/images/aws_proxy_lambda_calc_get_method_test_new_console.png)

## Integración 2: Crear un método `POST` con una carga JSON para llamar a la función de Lambda
<a name="api-as-lambda-proxy-expose-post-method-with-json-body-to-call-lambda-function"></a>

Al crear un método `POST` con una carga JSON para llamar a la función de Lambda, lo hace de tal manera que el cliente debe proporcionar la entrada necesaria a la función del backend en el cuerpo de la solicitud. Para garantizar que el cliente carga los datos de entrada correctos, habilitará la validación de solicitudes en la carga.

**Para crear un método `POST` con una carga JSON**

1. Seleccione el recurso **calc** y, a continuación, elija **Crear método**.

1. En **Tipo de método**, seleccione **POST**.

1. En **Tipo de integración**, seleccione **Servicio de AWS**.

1. En **Región de AWS**, seleccione la Región de AWS donde creó la función de Lambda.

1. En **Servicio de AWS**, seleccione **Lambda**.

1. Deje **Subdominio de AWS** en blanco.

1. En **Método HTTP**, seleccione **POST**.

1. En **Tipo de acción**, elija **Usar sustitución de ruta**. Esta opción nos permite especificar el ARN de la acción [Invoke](https://docs.aws.amazon.com/lambda/latest/dg/API_Invoke.html) para ejecutar nuestra función `Calc`. 

1. En **Sustitución de ruta**, escriba **2015-03-31/functions/arn:aws:lambda:*us-east-2*:*account-id*:function:Calc/invocations**. En ** *account-id***, introduzca su identificador de Cuenta de AWS. En ***us-east-2***, introduzca la Región de AWS donde creó la función de Lambda. 

1. En **Rol de ejecución**, escriba el ARN del rol para **lambda\$1invoke\$1function\$1assume\$1apigw\$1role**.

1. No cambie la configuración de **Caché de credenciales** ni **Tiempo de espera predeterminado**.

1. Elija **Crear método**.

Ahora vamos a crear un modelo de **entrada** para describir la estructura de los datos de entrada y validar el cuerpo de la solicitud entrante.

**Para crear el modelo de entrada**

1. En el panel de navegación principal, elija **Modelos**.

1. Seleccione **Crear modelo**.

1. En **Nombre**, escriba **input**.

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

   Si no se encuentra ningún tipo de contenido coincidente, no se realiza la validación de la solicitud. Para utilizar el mismo modelo independientemente del tipo de contenido, introduzca  **\$1default**.

1. En **Esquema del modelo**, escriba el siguiente modelo:

   ```
   {
       "type":"object",
       "properties":{
           "a":{"type":"number"},
           "b":{"type":"number"},
           "op":{"type":"string"}
       },
       "title":"input"
   }
   ```

1. Seleccione **Crear modelo**.

Ahora cree un modelo de **salida**. Este modelo describe la estructura de datos de la salida calculada desde el backend. Se puede utilizar para asignar los datos de la respuesta de integración a un modelo diferente. Este tutorial se basa en el comportamiento de paso a través y no utiliza este modelo.

**Para crear un modelo de salida**

1. Seleccione **Crear modelo**.

1. En **Nombre**, escriba **output**.

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

   Si no se encuentra ningún tipo de contenido coincidente, no se realiza la validación de la solicitud. Para utilizar el mismo modelo independientemente del tipo de contenido, introduzca  **\$1default**.

1. En **Esquema del modelo**, escriba el siguiente modelo:

   ```
   {
       "type":"object",
       "properties":{
           "c":{"type":"number"}
       },
       "title":"output"
   }
   ```

1. Seleccione **Crear modelo**.

Ahora cree un modelo de **resultados**. Este modelo describe la estructura de datos de los datos de respuesta devueltos. Hace referencia a los esquemas de **entrada** y **salida** definidos en su API.

**Para crear un modelo de resultados**

1. Seleccione **Crear modelo**.

1. En **Nombre**, escriba **result**.

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

   Si no se encuentra ningún tipo de contenido coincidente, no se realiza la validación de la solicitud. Para utilizar el mismo modelo independientemente del tipo de contenido, introduzca  **\$1default**.

1. En **Esquema del modelo**, introduzca el siguiente modelo con su *restapi-id*. El *restapi-id* aparece entre paréntesis en la parte superior de la consola en el siguiente flujo: `API Gateway > APIs > LambdaCalc (abc123).`

   ```
   {
       "type":"object",
       "properties":{
           "input":{
               "$ref":"https://apigateway.amazonaws.com/restapis/restapi-id/models/input"
           },
           "output":{
               "$ref":"https://apigateway.amazonaws.com/restapis/restapi-id/models/output"
           }
       },
       "title":"result"
   }
   ```

1. Seleccione **Crear modelo**.

Ahora configure la solicitud de método de su método POST para habilitar la validación de la solicitud en el cuerpo de la solicitud entrante.

**Habilitación de la validación de solicitudes en el método POST**

1. En el panel de navegación principal, seleccione **Recursos** y, a continuación, seleccione el método `POST` en el árbol de recursos.

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

1. En **Validador de solicitudes**, seleccione **Validar cuerpo**.

1. Seleccione **Cuerpo de la solicitud** y, a continuación, seleccione **Añadir modelo**.

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

   Si no se encuentra ningún tipo de contenido coincidente, no se realiza la validación de la solicitud. Para utilizar el mismo modelo independientemente del tipo de contenido, introduzca  **\$1default**.

1. En **Modelo**, seleccione **entrada**.

1. Seleccione **Save**.

Ahora puede probar el método `POST` para verificar que se ha configurado correctamente para invocar la función de Lambda.

**Para probar el método `POST`**

1. 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 **Cuerpo de la solicitud**, pegue la siguiente carga JSON.

   ```
   {
       "a": 1,
       "b": 2,
       "op": "+"
   }
   ```

1. Seleccione **Probar**

   Debería ver los siguientes datos de salida:

   ```
   {
     "a": 1,
     "b": 2,
     "op": "+",
     "c": 3
   }
   ```

## Integración 3: Crear un método `GET` con parámetros de ruta para llamar a la función de Lambda
<a name="api-as-lambda-proxy-expose-get-method-with-path-parameters-to-call-lambda-function"></a>

Ahora creará un método `GET` en un recurso especificado por una secuencia de parámetros de ruta para llamar a la función de Lambda del backend. Los valores de los parámetros de ruta especifican los datos de entrada a la función de Lambda. Definirá una plantilla de asignación para asignar los valores de los parámetros de ruta entrantes a la carga de la solicitud de integración necesaria.

La estructura de recursos de la API resultante será como la siguiente:

![\[Crear una API en API Gateway como proxy de Lambda\]](http://docs.aws.amazon.com/es_es/apigateway/latest/developerguide/images/aws_proxy_lambda_create_api_resources_new_console.png)


**Para crear un recurso **/\$1operand1\$1/\$1operand2\$1/\$1operator\$1****

1. Elija **Crear recurso**.

1. En **Ruta de recurso**, seleccione `/calc`.

1. En **Nombre del recurso**, escriba **\$1operand1\$1**.

1. Mantenga desactivado **CORS (uso compartido de recursos entre orígenes)**.

1. Elija **Crear recurso**.

1. En **Ruta de recurso**, seleccione `/calc/{operand1}/`.

1. En **Nombre del recurso**, escriba **\$1operand2\$1**.

1. Mantenga desactivado **CORS (uso compartido de recursos entre orígenes)**.

1. Elija **Crear recurso**.

1. En **Ruta de recurso**, seleccione `/calc/{operand1}/{operand2}/`.

1. En **Nombre del recurso**, escriba **\$1operator\$1**.

1. Mantenga desactivado **CORS (uso compartido de recursos entre orígenes)**.

1. Elija **Crear recurso**.

Esta vez utilizará la integración de Lambda incorporada en la consola de API Gateway para configurar la integración del método.

**Para configurar una integración del método**

1. Seleccione el recurso **/\$1operand1\$1/\$1operand2\$1/\$1operator\$1** y, a continuación, elija **Crear método**.

1. En **Tipo de método**, seleccione **GET**.

1. En **Tipo de integración**, seleccione **Lambda**.

1. Mantenga desactivada la **Integración de proxy Lambda**.

1. En **Función de Lambda**, seleccione la Región de AWS donde creó su función de Lambda e introduzca **Calc**.

1. Mantenga activado **Tiempo de espera predeterminado**.

1. Elija **Crear método**.

Ahora debe crear una plantilla de mapeo para mapear los tres parámetros de la ruta de la URL, declarados cuando se creó el recurso **/calc/\$1operand1\$1/\$1operand2\$1/\$1operator\$1**, con los valores de propiedad designados en el objeto JSON. Como las rutas URL deben estar codificadas como direcciones URL, el operador de división debe especificarse como `%2F` en lugar de `/`. Esta plantilla traduce `%2F` en `'/'` antes de pasarlo a la función de Lambda. 

**Para crear una plantilla de mapeo**

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**.

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

1. En **Cuerpo de la plantilla**, introduzca el siguiente código:

   ```
   {
      "a": "$input.params('operand1')",
      "b": "$input.params('operand2')",
      "op": #if($input.params('operator')=='%2F')"/"#{else}"$input.params('operator')"#end
   }
   ```

1. Seleccione **Save**.

Ahora puede probar el método `GET` para verificar que se ha configurado correctamente para invocar la función de Lambda y pasar el resultado original a través de la respuesta de integración sin mapear. 

**Para probar 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.

1. Para **Ruta**, haga lo siguiente:

   1. En **operand1**, introduzca **1**.

   1. En **operand2**, introduzca **1**.

   1. En **operator**, introduzca **\$1**.

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

1. El resultado debe tener el siguiente aspecto:  
![\[Pruebe el método GET en la consola de API Gateway.\]](http://docs.aws.amazon.com/es_es/apigateway/latest/developerguide/images/aws_proxy_lambda_calc_get_method_test_path_parm_new_console.png)

A continuación, creará el modelo de la estructura de datos de la carga de la respuesta del método detrás del esquema `result`.

De forma predeterminada, el cuerpo de la respuesta del método se asigna a un modelo vacío. Esto hará que el cuerpo de la respuesta de integración se transfiera sin asignación. Sin embargo, cuando genere un SDK para alguno de los lenguajes con establecimiento inflexible de tipos, como Java u Objective-C, los usuarios del SDK recibirán un objeto vacío como resultado. Para garantizar que el cliente REST y los clientes del SDK reciban el resultado deseado, debe crear los datos de la respuesta mediante un esquema predefinido. A continuación, definirá un modelo para el cuerpo de la respuesta del método y cómo crear una plantilla de asignación para traducir el cuerpo de la respuesta de integración al cuerpo de la respuesta del método.

**Para crear una respuesta del método**

1. En la pestaña **Respuesta del método**, en **Respuesta 200**, elija **Editar**.

1. En **Cuerpo de la respuesta**, seleccione **Agregar modelo**.

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

1. En **Modelo**, seleccione **resultado**.

1. Seleccione **Save**.

Al configurar el modelo para el cuerpo de la respuesta del método, nos aseguramos de que los datos de la respuesta se emitan en el objeto `result` de un determinado SDK. Para asegurarse de que los datos de la respuesta de integración se asignen según corresponda, necesitará una plantilla de asignación.

**Para crear una plantilla de mapeo**

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

1. Elija **Plantillas de mapeo**.

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

1. En **Cuerpo de la plantilla**, introduzca el siguiente código:

   ```
   #set($inputRoot = $input.path('$'))
   {
     "input" : {
       "a" : $inputRoot.a,
       "b" : $inputRoot.b,
       "op" : "$inputRoot.op"
     },
     "output" : {
       "c" : $inputRoot.c
     }
   }
   ```

1. Seleccione **Save**.

**Para probar la plantilla de mapeo**

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

1. Para **Ruta**, haga lo siguiente:

   1. En **operand1**, introduzca **1**.

   1. En **operand2**, introduzca **2**.

   1. En **operator**, introduzca **\$1**.

1. Seleccione **Probar**

1. El resultado será parecido al siguiente:

   ```
   {
     "input": {
       "a": 1,
       "b": 2,
       "op": "+"
     },
     "output": {
       "c": 3
     }
   }
   ```

En este momento, solo puede llamar a la API utilizando la característica **Prueba** de la consola de API Gateway. Para hacer que esté disponible para los clientes, debe implementar la API. Asegúrese siempre para volver a implementar la API, cada vez que agrega, modifica o elimina un recurso o un método, actualizar una asignación de datos o actualiza la configuración de la etapa. De lo contrario, las nuevas características o actualizaciones no estarán disponibles para los clientes de la API.

**Para implementar la API**

1. Elija **Implementar API**.

1. En **Etapa**, seleccione **Nueva etapa**.

1. En **Stage name (Nombre de etapa)**, escriba **Prod**.

1. (Opcional) En **Description (Descripción)**, introduzca una descripción.

1. Elija **Implementar**.

1.  (Opcional) En **Detalles de la etapa**, para **URL de invocación**, puede elegir el icono de copia para copiar la URL de invocación de su API. Puede utilizar esto con herramientas como [Postman](https://www.postman.com) y [cURL](https://curl.se/) para probar la API.

**nota**  
Vuelva a implementar la API cada vez que agrega, modifica o elimina un recurso o un método, actualiza una asignación de datos o actualiza la configuración de la etapa. De lo contrario, las nuevas características o actualizaciones no estarán disponibles para los clientes de la API.

# Definiciones de OpenAPI de una API de ejemplo integrada con una función de Lambda
<a name="api-as-lambda-proxy-export-swagger-with-extensions"></a>

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

```
{
  "swagger": "2.0",
  "info": {
    "version": "2017-04-20T04:08:08Z",
    "title": "LambdaCalc"
  },
  "host": "uojnr9hd57.execute-api.us-east-1.amazonaws.com",
  "basePath": "/test",
  "schemes": [
    "https"
  ],
  "paths": {
    "/calc": {
      "get": {
        "consumes": [
          "application/json"
        ],
        "produces": [
          "application/json"
        ],
        "parameters": [
          {
            "name": "operand2",
            "in": "query",
            "required": true,
            "type": "string"
          },
          {
            "name": "operator",
            "in": "query",
            "required": true,
            "type": "string"
          },
          {
            "name": "operand1",
            "in": "query",
            "required": true,
            "type": "string"
          }
        ],
        "responses": {
          "200": {
            "description": "200 response",
            "schema": {
              "$ref": "#/definitions/Result"
            },
            "headers": {
              "operand_1": {
                "type": "string"
              },
              "operand_2": {
                "type": "string"
              },
              "operator": {
                "type": "string"
              }
            }
          }
        },
        "x-amazon-apigateway-request-validator": "Validate query string parameters and headers",
        "x-amazon-apigateway-integration": {
          "credentials": "arn:aws:iam::123456789012:role/apigAwsProxyRole",
          "responses": {
            "default": {
              "statusCode": "200",
              "responseParameters": {
                "method.response.header.operator": "integration.response.body.op",
                "method.response.header.operand_2": "integration.response.body.b",
                "method.response.header.operand_1": "integration.response.body.a"
              },
              "responseTemplates": {
                "application/json": "#set($res = $input.path('$'))\n{\n    \"result\": \"$res.a, $res.b, $res.op => $res.c\",\n  \"a\" : \"$res.a\",\n  \"b\" : \"$res.b\",\n  \"op\" : \"$res.op\",\n  \"c\" : \"$res.c\"\n}"
              }
            }
          },
          "uri": "arn:aws:apigateway:us-west-2:lambda:path/2015-03-31/functions/arn:aws:lambda:us-west-2:123456789012:function:Calc/invocations",
          "passthroughBehavior": "when_no_match",
          "httpMethod": "POST",
          "requestTemplates": {
            "application/json": "{\n    \"a\":  \"$input.params('operand1')\",\n    \"b\":  \"$input.params('operand2')\", \n    \"op\": \"$input.params('operator')\"   \n}"
          },
          "type": "aws"
        }
      },
      "post": {
        "consumes": [
          "application/json"
        ],
        "produces": [
          "application/json"
        ],
        "parameters": [
          {
            "in": "body",
            "name": "Input",
            "required": true,
            "schema": {
              "$ref": "#/definitions/Input"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "200 response",
            "schema": {
              "$ref": "#/definitions/Result"
            }
          }
        },
        "x-amazon-apigateway-request-validator": "Validate body",
        "x-amazon-apigateway-integration": {
          "credentials": "arn:aws:iam::123456789012:role/apigAwsProxyRole",
          "responses": {
            "default": {
              "statusCode": "200",
              "responseTemplates": {
                "application/json": "#set($inputRoot = $input.path('$'))\n{\n  \"a\" : $inputRoot.a,\n  \"b\" : $inputRoot.b,\n  \"op\" : $inputRoot.op,\n  \"c\" : $inputRoot.c\n}"
              }
            }
          },
          "uri": "arn:aws:apigateway:us-west-2:lambda:path/2015-03-31/functions/arn:aws:lambda:us-west-2:123456789012:function:Calc/invocations",
          "passthroughBehavior": "when_no_templates",
          "httpMethod": "POST",
          "type": "aws"
        }
      }
    },
    "/calc/{operand1}/{operand2}/{operator}": {
      "get": {
        "consumes": [
          "application/json"
        ],
        "produces": [
          "application/json"
        ],
        "parameters": [
          {
            "name": "operand2",
            "in": "path",
            "required": true,
            "type": "string"
          },
          {
            "name": "operator",
            "in": "path",
            "required": true,
            "type": "string"
          },
          {
            "name": "operand1",
            "in": "path",
            "required": true,
            "type": "string"
          }
        ],
        "responses": {
          "200": {
            "description": "200 response",
            "schema": {
              "$ref": "#/definitions/Result"
            }
          }
        },
        "x-amazon-apigateway-integration": {
          "credentials": "arn:aws:iam::123456789012:role/apigAwsProxyRole",
          "responses": {
            "default": {
              "statusCode": "200",
              "responseTemplates": {
                "application/json": "#set($inputRoot = $input.path('$'))\n{\n  \"input\" : {\n    \"a\" : $inputRoot.a,\n    \"b\" : $inputRoot.b,\n    \"op\" : \"$inputRoot.op\"\n  },\n  \"output\" : {\n    \"c\" : $inputRoot.c\n  }\n}"
              }
            }
          },
          "uri": "arn:aws:apigateway:us-west-2:lambda:path/2015-03-31/functions/arn:aws:lambda:us-west-2:123456789012:function:Calc/invocations",
          "passthroughBehavior": "when_no_templates",
          "httpMethod": "POST",
          "requestTemplates": {
            "application/json": "{\n   \"a\": \"$input.params('operand1')\",\n   \"b\": \"$input.params('operand2')\",\n   \"op\": #if($input.params('operator')=='%2F')\"/\"#{else}\"$input.params('operator')\"#end\n   \n}"
          },
          "contentHandling": "CONVERT_TO_TEXT",
          "type": "aws"
        }
      }
    }
  },
  "definitions": {
    "Input": {
      "type": "object",
      "required": [
        "a",
        "b",
        "op"
      ],
      "properties": {
        "a": {
          "type": "number"
        },
        "b": {
          "type": "number"
        },
        "op": {
          "type": "string",
          "description": "binary op of ['+', 'add', '-', 'sub', '*', 'mul', '%2F', 'div']"
        }
      },
      "title": "Input"
    },
    "Output": {
      "type": "object",
      "properties": {
        "c": {
          "type": "number"
        }
      },
      "title": "Output"
    },
    "Result": {
      "type": "object",
      "properties": {
        "input": {
          "$ref": "#/definitions/Input"
        },
        "output": {
          "$ref": "#/definitions/Output"
        }
      },
      "title": "Result"
    }
  },
  "x-amazon-apigateway-request-validators": {
    "Validate body": {
      "validateRequestParameters": false,
      "validateRequestBody": true
    },
    "Validate query string parameters and headers": {
      "validateRequestParameters": true,
      "validateRequestBody": false
    }
  }
}
```

------