

Esta es la guía para desarrolladores de AWS CDK v2. La primera versión del CDK pasó a la etapa de mantenimiento el 1.° de junio de 2022 y no cuenta con soporte desde el 1.° de junio de 2023.

Las traducciones son generadas a través de traducción automática. En caso de conflicto entre la traducción y la version original de inglés, prevalecerá la version en inglés.

# Tutorial: cómo crear una aplicación Hello World sin servidor
<a name="serverless-example"></a>

En este tutorial, se utiliza AWS Cloud Development Kit (AWS CDK) para crear una sencilla aplicación `Hello World` sin servidor que incluye un backend de API básico que consta de lo siguiente:
+  **API de REST de Amazon API Gateway**: proporciona un punto de conexión HTTP que se utiliza para invocar la función mediante una solicitud HTTP GET.
+  **Función de AWS Lambda**: función que devuelve un mensaje `Hello World!` cuando se invoca con el punto de conexión HTTP.
+  **Integraciones y permisos**: detalles de configuración y permisos para que sus activos interactúen entre sí y realicen acciones, como escribir registros en Amazon CloudWatch.

El siguiente diagrama muestra los componentes de esta aplicación:

![\[Diagrama de una función de Lambda que se invoca cuando envía una solicitud GET al punto de conexión de la API Gateway.\]](http://docs.aws.amazon.com/es_es/cdk/v2/guide/images/serverless-example-01.png)


Para este tutorial, creará e interactuará con su aplicación en los siguientes pasos:

1. Crear un proyecto de AWS CDK

1. Defina una función de Lambda y una API de REST de API Gateway mediante constructos L2 de la Biblioteca de constructos de AWS.

1. Implemente su aplicación en la nube de AWS.

1. Interactúe con su aplicación en la nube de AWS.

1. Elimine la aplicación de muestra de la nube de AWS.

## Requisitos previos
<a name="serverless-example-pre"></a>

Antes de comenzar este tutorial, debe completar lo siguiente:
+ Cree una cuenta de AWS e instale y configure la interfaz de línea de comandos de AWS (AWS CLI).
+ Instale Node.js y `npm`.
+ Instale el kit de herramientas de CDK a nivel mundial, utilizando `npm install -g aws-cdk`.

Para obtener más información, consulte [Introducción a AWS CDK](getting-started.md).

Se recomienda tener conocimientos básicos sobre:
+  [¿Qué es el AWS CDK?](home.md) para obtener una introducción básica a AWS CDK.
+  [Conozca los conceptos básicos del AWS CDK](core-concepts.md) para obtener una descripción general de los conceptos principales del AWS CDK.

## Paso 1: cómo crear un proyecto
<a name="serverless-example-project"></a>

En este paso, cree un nuevo proyecto CDK al utilizar el comando `cdk init` de la CLI de AWS CDK.

 **Crear un proyecto CDK**   

1. Desde un directorio inicial de su elección, cree y navegue a un directorio de proyecto llamado `cdk-hello-world` en su máquina:

   ```
   $ mkdir cdk-hello-world && cd cdk-hello-world
   ```

1. Para crear un nuevo proyecto en su lenguaje de programación preferido, use el comando `cdk init`:  
**Example**  

------
#### [ TypeScript ]

   ```
   $ cdk init --language typescript
   ```

   Instale bibliotecas de AWS CDK:

   ```
   $ npm install aws-cdk-lib constructs
   ```

------
#### [ JavaScript ]

   ```
   $ cdk init --language javascript
   ```

   Instale bibliotecas de AWS CDK:

   ```
   $ npm install aws-cdk-lib constructs
   ```

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

   ```
   $ cdk init --language python
   ```

   Active el entorno virtual:

   ```
   $ source .venv/bin/activate # On Windows, run '.\venv\Scripts\activate' instead
   ```

   Instale bibliotecas de AWS CDK y las dependencias del proyecto:

   ```
   (.venv)$ python3 -m pip install -r requirements.txt
   ```

------
#### [ Java ]

   ```
   $ cdk init --language java
   ```

   Instale bibliotecas de AWS CDK y las dependencias del proyecto:

   ```
   $ mvn package
   ```

------
#### [ C\$1 ]

   ```
   $ cdk init --language csharp
   ```

   Instale bibliotecas de AWS CDK y las dependencias del proyecto:

   ```
   $ dotnet restore src
   ```

------
#### [ Go ]

   ```
   $ cdk init --language go
   ```

   Instale las dependencias del proyecto:

   ```
   $ go get github.com/aws/aws-cdk-go/awscdk/v2
   $ go get github.com/aws/aws-cdk-go/awscdk/v2/awslambda
   $ go get github.com/aws/aws-cdk-go/awscdk/v2/awsapigateway
   $ go mod tidy
   ```

------

   La CLI de CDK crea un proyecto con la siguiente estructura:  
**Example**  

------
#### [ TypeScript ]

   ```
   cdk-hello-world
   ├── .git
   ├── .gitignore
   ├── .npmignore
   ├── README.md
   ├── bin
   │   └── cdk-hello-world.ts
   ├── cdk.json
   ├── jest.config.js
   ├── lib
   │   └── cdk-hello-world-stack.ts
   ├── node_modules
   ├── package-lock.json
   ├── package.json
   ├── test
   │   └── cdk-hello-world.test.ts
   └── tsconfig.json
   ```

------
#### [ JavaScript ]

   ```
   cdk-hello-world
   ├── .git
   ├── .gitignore
   ├── .npmignore
   ├── README.md
   ├── bin
   │   └── cdk-hello-world.js
   ├── cdk.json
   ├── jest.config.js
   ├── lib
   │   └── cdk-hello-world-stack.js
   ├── node_modules
   ├── package-lock.json
   ├── package.json
   └── test
       └── cdk-hello-world.test.js
   ```

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

   ```
   cdk-hello-world
   ├── .git
   ├── .gitignore
   ├── .venv
   ├── README.md
   ├── app.py
   ├── cdk.json
   ├── cdk_hello_world
   │   ├── __init__.py
   │   └── cdk_hello_world_stack.py
   ├── requirements-dev.txt
   ├── requirements.txt
   ├── source.bat
   └── tests
   ```

------
#### [ Java ]

   ```
   cdk-hello-world
   ├── .git
   ├── .gitignore
   ├── README.md
   ├── cdk.json
   ├── pom.xml
   ├── src
   │   ├── main
   │   │   └── java
   │   │       └── com
   │   │           └── myorg
   │   │               ├── CdkHelloWorldApp.java
   │   │               └── CdkHelloWorldStack.java
   └── target
   ```

------
#### [ C\$1 ]

   ```
   cdk-hello-world
   ├── .git
   ├── .gitignore
   ├── README.md
   ├── cdk.json
   └── src
       ├── CdkHelloWorld
       │   ├── CdkHelloWorld.csproj
       │   ├── CdkHelloWorldStack.cs
       │   ├── GlobalSuppressions.cs
       │   └── Program.cs
       └── CdkHelloWorld.sln
   ```

------
#### [ Go ]

   ```
   cdk-hello-world
   ├── .git
   ├── .gitignore
   ├── README.md
   ├── cdk-hello-world.go
   ├── cdk-hello-world_test.go
   ├── cdk.json
   ├── go.mod
   └── go.sum
   ```

------

La CLI de CDK crea automáticamente una aplicación de CDK que contiene una sola pila. La instancia de la aplicación de CDK se crea a partir de la clase ` [App](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.App.html) `. La siguiente es una parte del archivo de la aplicación de CDK:

**Example**  
Se encuentra en `bin/cdk-hello-world.ts`:  

```
#!/usr/bin/env node
import 'source-map-support/register';
import * as cdk from 'aws-cdk-lib';
import { CdkHelloWorldStack } from '../lib/cdk-hello-world-stack';

const app = new cdk.App();
new CdkHelloWorldStack(app, 'CdkHelloWorldStack', {
});
```
Se encuentra en `bin/cdk-hello-world.js`:  

```
#!/usr/bin/env node
const cdk = require('aws-cdk-lib');
const { CdkHelloWorldStack } = require('../lib/cdk-hello-world-stack');
const app = new cdk.App();
new CdkHelloWorldStack(app, 'CdkHelloWorldStack', {
});
```
Se encuentra en `app.py`:  

```
#!/usr/bin/env python3
import os
import aws_cdk as cdk
from cdk_hello_world.cdk_hello_world_stack import CdkHelloWorldStack

app = cdk.App()
CdkHelloWorldStack(app, "CdkHelloWorldStack",)
app.synth()
```
Se encuentra en `src/main/java/…​/CdkHelloWorldApp.java`:  

```
package com.myorg;

import software.amazon.awscdk.App;
import software.amazon.awscdk.Environment;
import software.amazon.awscdk.StackProps;

import java.util.Arrays;

public class JavaApp {
    public static void main(final String[] args) {
        App app = new App();

        new JavaStack(app, "JavaStack", StackProps.builder()
                .build());

        app.synth();
    }
}
```
Se encuentra en `src/CdkHelloWorld/Program.cs`:  

```
using Amazon.CDK;
using System;
using System.Collections.Generic;
using System.Linq;

namespace CdkHelloWorld
{
    sealed class Program
    {
        public static void Main(string[] args)
        {
            var app = new App();
            new CdkHelloWorldStack(app, "CdkHelloWorldStack", new StackProps
            {

            });
            app.Synth();
        }
    }
}
```
Se encuentra en `cdk-hello-world.go`:  

```
package main
import (
    "github.com/aws/aws-cdk-go/awscdk/v2"
    "github.com/aws/constructs-go/constructs/v10"
    "github.com/aws/jsii-runtime-go"
)

// ...

func main() {
    defer jsii.Close()
    app := awscdk.NewApp(nil)
    NewCdkHelloWorldStack(app, "CdkHelloWorldStack", &CdkHelloWorldStackProps{
        awscdk.StackProps{
            Env: env(),
        },
    })
    app.Synth(nil)
}

func env() *awscdk.Environment {
    return nil
}
```

## Paso 2: cómo crear su función de Lambda
<a name="serverless-example-function"></a>

Dentro de su proyecto de CDK, cree un directorio `lambda` que incluya un archivo nuevo `hello.js`. A continuación, se muestra un ejemplo:

**Example**  
Desde la raíz del proyecto, ejecute lo siguiente:  

```
$ mkdir lambda && cd lambda
$ touch hello.js
```
Ahora debería agregarse lo siguiente a su proyecto de CDK:  

```
cdk-hello-world
└── lambda
    └── hello.js
```
Desde la raíz del proyecto, ejecute lo siguiente:  

```
$ mkdir lambda && cd lambda
$ touch hello.js
```
Ahora debería agregarse lo siguiente a su proyecto de CDK:  

```
cdk-hello-world
└── lambda
    └── hello.js
```
Desde la raíz del proyecto, ejecute lo siguiente:  

```
$ mkdir lambda && cd lambda
$ touch hello.js
```
Ahora debería agregarse lo siguiente a su proyecto de CDK:  

```
cdk-hello-world
└── lambda
    └── hello.js
```
Desde la raíz del proyecto, ejecute lo siguiente:  

```
$ mkdir -p src/main/resources/lambda
$ cd src/main/resources/lambda
$ touch hello.js
```
Ahora debería agregarse lo siguiente a su proyecto de CDK:  

```
cdk-hello-world
└── src
    └── main
        └──resources
            └──lambda
                └──hello.js
```
Desde la raíz del proyecto, ejecute lo siguiente:  

```
$ mkdir lambda && cd lambda
$ touch hello.js
```
Ahora debería agregarse lo siguiente a su proyecto de CDK:  

```
cdk-hello-world
└── lambda
    └── hello.js
```
Desde la raíz del proyecto, ejecute lo siguiente:  

```
$ mkdir lambda && cd lambda
$ touch hello.js
```
Ahora debería agregarse lo siguiente a su proyecto de CDK:  

```
cdk-hello-world
└── lambda
    └── hello.js
```

**nota**  
Para simplificar este tutorial, utilizamos una función de Lambda JavaScript para todos los lenguajes de programación CDK.

Para definir la función de Lambda, agregue lo siguiente al archivo recién creado:

```
exports.handler = async (event) => {
    return {
        statusCode: 200,
        headers: { "Content-Type": "text/plain" },
        body: JSON.stringify({ message: "Hello, World!" }),
    };
};
```

## Paso 3: cómo definir las construcciones
<a name="serverless-example-constructs"></a>

En este paso, definirá sus activos de Lambda y API Gateway a través de los constructos de nivel 2 de AWS CDK.

Abra el archivo del proyecto que define su pila CDK. Modificará este archivo para definir sus constructos fijos. A continuación se muestra un ejemplo del archivo de pila inicial:

**Example**  
Se encuentra en `lib/cdk-hello-world-stack.ts`:  

```
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';

export class CdkHelloWorldStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    // Your constructs will go here

  }
}
```
Se encuentra en `lib/cdk-hello-world-stack.js`:  

```
const { Stack, Duration } = require('aws-cdk-lib');
const lambda = require('aws-cdk-lib/aws-lambda');
const apigateway = require('aws-cdk-lib/aws-apigateway');

class CdkHelloWorldStack extends Stack {

  constructor(scope, id, props) {
    super(scope, id, props);

    // Your constructs will go here

  }
}

module.exports = { CdkHelloWorldStack }
```
Se encuentra en `cdk_hello_world/cdk_hello_world_stack.py`:  

```
from aws_cdk import Stack
from constructs import Construct

class CdkHelloWorldStack(Stack):
    def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
        super().__init__(scope, construct_id, **kwargs)

          // Your constructs will go here
```
Se encuentra en `src/main/java/…​/CdkHelloWorldStack.java`:  

```
package com.myorg;

import software.constructs.Construct;
import software.amazon.awscdk.Stack;
import software.amazon.awscdk.StackProps;

public class CdkHelloWorldStack extends Stack {
    public CdkHelloWorldStack(final Construct scope, final String id) {
        this(scope, id, null);
    }

    public CdkHelloWorldStack(final Construct scope, final String id, final StackProps props) {
        super(scope, id, props);

        // Your constructs will go here
    }
}
```
Se encuentra en `src/CdkHelloWorld/CdkHelloWorldStack.cs`:  

```
using Amazon.CDK;
using Constructs;

namespace CdkHelloWorld
{
    public class CdkHelloWorldStack : Stack
    {
        internal CdkHelloWorldStack(Construct scope, string id, IStackProps props = null) : base(scope, id, props)
        {
            // Your constructs will go here
        }
    }
}
```
Ubicado en `cdk-hello-world.go`:  

```
package main

import (
    "github.com/aws/aws-cdk-go/awscdk/v2"
    "github.com/aws/constructs-go/constructs/v10"
    "github.com/aws/jsii-runtime-go"
)

type CdkHelloWorldStackProps struct {
    awscdk.StackProps
}

func NewCdkHelloWorldStack(scope constructs.Construct, id string, props *CdkHelloWorldStackProps) awscdk.Stack {
    var sprops awscdk.StackProps
    if props != nil {
        sprops = props.StackProps
    }
    stack := awscdk.NewStack(scope, &id, &sprops)

    // Your constructs will go here

    return stack
}

func main() {

    // ...

}

func env() *awscdk.Environment {

    return nil

}
```

En este archivo, AWS CDK realiza las siguientes tareas:
+ Su instancia de pila CDK se crea a partir de la clase ` [Stack](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Stack.html) `.
+ La clase ` [Constructs](https://docs.aws.amazon.com/cdk/api/v2/docs/constructs-readme.html) ` base se importa y se proporciona como ámbito o elemento principal de la instancia de la pila.

### Defina activos de la función de Lambda
<a name="serverless-example-constructs-lambda"></a>

Para definir su activo de la función de Lambda, importe y utilice el constructo L2 ` [aws-lambda](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_lambda-readme.html) ` de la Biblioteca de constructos de AWS.

Modifique el archivo de pila de la siguiente manera:

**Example**  

```
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
// Import Lambda L2 construct
import * as lambda from 'aws-cdk-lib/aws-lambda';

export class CdkHelloWorldStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    // Define the Lambda function resource
    const helloWorldFunction = new lambda.Function(this, 'HelloWorldFunction', {
      runtime: lambda.Runtime.NODEJS_20_X, // Choose any supported Node.js runtime
      code: lambda.Code.fromAsset('lambda'), // Points to the lambda directory
      handler: 'hello.handler', // Points to the 'hello' file in the lambda directory
    });
  }
}
```

```
const { Stack, Duration } = require('aws-cdk-lib');
// Import Lambda L2 construct
const lambda = require('aws-cdk-lib/aws-lambda');


class CdkHelloWorldStack extends Stack {
  constructor(scope, id, props) {
    super(scope, id, props);

    // Define the Lambda function resource
    const helloWorldFunction = new lambda.Function(this, 'HelloWorldFunction', {
      runtime: lambda.Runtime.NODEJS_20_X, // Choose any supported Node.js runtime
      code: lambda.Code.fromAsset('lambda'), // Points to the lambda directory
      handler: 'hello.handler', // Points to the 'hello' file in the lambda directory
    });
  }
}

module.exports = { CdkHelloWorldStack }
```

```
from aws_cdk import (
    Stack,
    # Import Lambda L2 construct
    aws_lambda as _lambda,
)
# ...

class CdkHelloWorldStack(Stack):

    def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
        super().__init__(scope, construct_id, **kwargs)

        # Define the Lambda function resource
        hello_world_function = _lambda.Function(
            self,
            "HelloWorldFunction",
            runtime = _lambda.Runtime.NODEJS_20_X, # Choose any supported Node.js runtime
            code = _lambda.Code.from_asset("lambda"), # Points to the lambda directory
            handler = "hello.handler", # Points to the 'hello' file in the lambda directory
        )
```
Importamos el módulo `aws_lambda` como `\_lambda`, ya que `lambda` es un identificador incorporado en Python.

```
// ...
// Import Lambda L2 construct
import software.amazon.awscdk.services.lambda.Code;
import software.amazon.awscdk.services.lambda.Function;
import software.amazon.awscdk.services.lambda.Runtime;

public class CdkHelloWorldStack extends Stack {
    public CdkHelloWorldStack(final Construct scope, final String id) {
        this(scope, id, null);
    }

    public CdkHelloWorldStack(final Construct scope, final String id, final StackProps props) {
        super(scope, id, props);

        // Define the Lambda function resource
        Function helloWorldFunction = Function.Builder.create(this, "HelloWorldFunction")
                .runtime(Runtime.NODEJS_20_X)  // Choose any supported Node.js runtime
                .code(Code.fromAsset("src/main/resources/lambda")) // Points to the lambda directory
                .handler("hello.handler")  // Points to the 'hello' file in the lambda directory
                .build();
    }
}
```

```
// ...
// Import Lambda L2 construct
using Amazon.CDK.AWS.Lambda;

namespace CdkHelloWorld
{
    public class CdkHelloWorldStack : Stack
    {
        internal CdkHelloWorldStack(Construct scope, string id, IStackProps props = null) : base(scope, id, props)
        {
            // Define the Lambda function resource
            var helloWorldFunction = new Function(this, "HelloWorldFunction", new FunctionProps
            {
                Runtime = Runtime.NODEJS_20_X, // Choose any supported Node.js runtime
                Code = Code.FromAsset("lambda"), // Points to the lambda directory
                Handler = "hello.handler" // Points to the 'hello' file in the lambda directory
            });
        }
    }
}
```

```
package main

import (
    // ...
    // Import Lambda L2 construct
    "github.com/aws/aws-cdk-go/awscdk/v2/awslambda"
    // Import S3 assets construct
    "github.com/aws/aws-cdk-go/awscdk/v2/awss3assets"
    // ...
)

// ...

func NewCdkHelloWorldStack(scope constructs.Construct, id string, props *CdkHelloWorldStackProps) awscdk.Stack {
    var sprops awscdk.StackProps
    if props != nil {
        sprops = props.StackProps
    }
    stack := awscdk.NewStack(scope, &id, &sprops)

    // Define the Lambda function resource
    helloWorldFunction := awslambda.NewFunction(stack, jsii.String("HelloWorldFunction"), &awslambda.FunctionProps{
        Runtime: awslambda.Runtime_NODEJS_20_X(), // Choose any supported Node.js runtime
        Code:    awslambda.Code_FromAsset(jsii.String("lambda"), &awss3assets.AssetOptions{}), // Points to the lambda directory
        Handler: jsii.String("hello.handler"), // Points to the 'hello' file in the lambda directory
    })

    return stack
}

// ...
```

A continuación, se crea un activo de función de Lambda y se definen las siguientes propiedades:
+  `runtime` – El entorno en el que se ejecuta la función. En este caso, utilizamos la versión 20.x de Node.js.
+  `code` – La ruta del código de la función en su máquina local.
+  `handler` – El nombre del archivo que contiene el código de la función.

### Defina su recurso de API de REST de API Gateway
<a name="serverless-example-constructs-api"></a>

Para definir su recurso REST API de API Gateway, importe y utilice el constructo L2 ` [aws-apigateway](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_apigateway-readme.html) ` de la Biblioteca de constructos de AWS.

Modifique el archivo de pila de la siguiente manera:

**Example**  

```
// ...
//Import API Gateway L2 construct
import * as apigateway from 'aws-cdk-lib/aws-apigateway';


export class CdkHelloWorldStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    // ...

    // Define the API Gateway resource
    const api = new apigateway.LambdaRestApi(this, 'HelloWorldApi', {
      handler: helloWorldFunction,
      proxy: false,
    });

    // Define the '/hello' resource with a GET method
    const helloResource = api.root.addResource('hello');
    helloResource.addMethod('GET');
  }
}
```

```
// ...
// Import API Gateway L2 construct
const apigateway = require('aws-cdk-lib/aws-apigateway');


class CdkHelloWorldStack extends Stack {
  constructor(scope, id, props) {
    super(scope, id, props);

    // ...

    // Define the API Gateway resource
    const api = new apigateway.LambdaRestApi(this, 'HelloWorldApi', {
      handler: helloWorldFunction,
      proxy: false,
    });

    // Define the '/hello' resource with a GET method
    const helloResource = api.root.addResource('hello');
    helloResource.addMethod('GET');
  };
};

// ...
```

```
from aws_cdk import (
    # ...
    # Import API Gateway L2 construct
    aws_apigateway as apigateway,
)
from constructs import Construct

class CdkHelloWorldStack(Stack):

    def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
        super().__init__(scope, construct_id, **kwargs)

        # ...

        # Define the API Gateway resource
        api = apigateway.LambdaRestApi(
            self,
            "HelloWorldApi",
            handler = hello_world_function,
            proxy = False,
        )

        # Define the '/hello' resource with a GET method
        hello_resource = api.root.add_resource("hello")
        hello_resource.add_method("GET")
```

```
// ...
// Import API Gateway L2 construct
import software.amazon.awscdk.services.apigateway.LambdaRestApi;
import software.amazon.awscdk.services.apigateway.Resource;

public class CdkHelloWorldStack extends Stack {
    public CdkHelloWorldStack(final Construct scope, final String id) {
        this(scope, id, null);
    }

    public CdkHelloWorldStack(final Construct scope, final String id, final StackProps props) {
        super(scope, id, props);

        // ...

        // Define the API Gateway resource
        LambdaRestApi api = LambdaRestApi.Builder.create(this, "HelloWorldApi")
                .handler(helloWorldFunction)
                .proxy(false) // Turn off default proxy integration
                .build();

        // Define the '/hello' resource and its GET method
        Resource helloResource = api.getRoot().addResource("hello");
        helloResource.addMethod("GET");
    }
}
```

```
// ...
// Import API Gateway L2 construct
using Amazon.CDK.AWS.APIGateway;

namespace CdkHelloWorld
{
    public class CdkHelloWorldStack : Stack
    {
        internal CdkHelloWorldStack(Construct scope, string id, IStackProps props = null) : base(scope, id, props)
        {
           // ...

            // Define the API Gateway resource
            var api = new LambdaRestApi(this, "HelloWorldApi", new LambdaRestApiProps
            {
                Handler = helloWorldFunction,
                Proxy = false
            });

            // Add a '/hello' resource with a GET method
            var helloResource = api.Root.AddResource("hello");
            helloResource.AddMethod("GET");
        }
    }
}
```

```
// ...

import (
    // ...
    // Import Api Gateway L2 construct
    "github.com/aws/aws-cdk-go/awscdk/v2/awsapigateway"
    // ...
)

// ...

func NewCdkHelloWorldStack(scope constructs.Construct, id string, props *CdkHelloWorldStackProps) awscdk.Stack {
    var sprops awscdk.StackProps
    if props != nil {
        sprops = props.StackProps
    }
    stack := awscdk.NewStack(scope, &id, &sprops)

    // Define the Lambda function resource
    // ...

    // Define the API Gateway resource
    api := awsapigateway.NewLambdaRestApi(stack, jsii.String("HelloWorldApi"), &awsapigateway.LambdaRestApiProps{
        Handler: helloWorldFunction,
        Proxy: jsii.Bool(false),
    })

    // Add a '/hello' resource with a GET method
    helloResource := api.Root().AddResource(jsii.String("hello"), &awsapigateway.ResourceOptions{})
    helloResource.AddMethod(jsii.String("GET"), awsapigateway.NewLambdaIntegration(helloWorldFunction, &awsapigateway.LambdaIntegrationOptions{}), &awsapigateway.MethodOptions{})

    return stack
}

// ...
```

Aquí, se crea un recurso de API de REST de API Gateway, junto con lo siguiente:
+ Una integración entre la función de Lambda y API de REST, que permite a la API invocar su función. Esto incluye la creación de un activo de permisos de Lambda.
+ Un nuevo nombre de activo o ruta `hello` que se agrega a la raíz del punto de conexión de la API. Esto crea un nuevo punto de conexión que agrega `/hello` a su URL base.
+ Un método GET para el recurso `hello`. Cuando se envía una solicitud GET al punto de conexión `/hello` de Lambda, se invoca la función de Lambda y se devuelve su respuesta.

## Paso 4: cómo preparar la aplicación para su implementación
<a name="serverless-example-deploy-prepare"></a>

En este paso, prepare la aplicación para su implementación a través de la compilación y, si es necesario, realice una validación básica con el comando `cdk synth` de la CLI de AWS CDK.

Si es necesario, cree la aplicación:

**Example**  
Desde la raíz del proyecto, ejecute lo siguiente:  

```
$ npm run build
```
No es necesario construir.
No es necesario construir.
Desde la raíz del proyecto, ejecute lo siguiente:  

```
$ mvn package
```
Desde la raíz del proyecto, ejecute lo siguiente:  

```
$ dotnet build src
```
No es necesario construir.

Ejecute `cdk synth` para sintetizar una plantilla de AWS CloudFormation a partir de su código CDK. Al utilizar constructos L2, muchos de los detalles de configuración necesarios por AWS CloudFormation para facilitar la interacción entre la función de Lambda y API de REST los proporciona el AWS CDK.

Desde la raíz del proyecto, ejecute lo siguiente:

```
$ cdk synth
```

**nota**  
Si recibe un error como el siguiente, verifique que se encuentra en el directorio `cdk-hello-world` e inténtelo de nuevo:  

```
--app is required either in command-line, in cdk.json or in ~/.cdk.json
```

Si se ejecuta correctamente, la CLI de AWS CDK generará la plantilla de AWS CloudFormation en formato `YAML` en la línea de comandos solicitados. También se guarda una plantilla `JSON` formateada en el directorio `cdk.out`.

A continuación, se muestra un ejemplo de resultado de la plantilla de AWS CloudFormation:

### Plantilla de AWS CloudFormation
<a name="serverless-example-deploy-cfn"></a>

```
Resources:
  HelloWorldFunctionServiceRoleunique-identifier:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Statement:
          - Action: sts:AssumeRole
            Effect: Allow
            Principal:
              Service: lambda.amazonaws.com
        Version: "2012-10-17"		 	 	 
      ManagedPolicyArns:
        - Fn::Join:
            - ""
            - - "arn:"
              - Ref: AWS::Partition
              - :iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
    Metadata:
      aws:cdk:path: CdkHelloWorldStack/HelloWorldFunction/ServiceRole/Resource
  HelloWorldFunctionunique-identifier:
    Type: AWS::Lambda::Function
    Properties:
      Code:
        S3Bucket:
          Fn::Sub: cdk-unique-identifier-assets-${AWS::AccountId}-${AWS::Region}
        S3Key: unique-identifier.zip
      Handler: hello.handler
      Role:
        Fn::GetAtt:
          - HelloWorldFunctionServiceRoleunique-identifier
          - Arn
      Runtime: nodejs20.x
    DependsOn:
      - HelloWorldFunctionServiceRoleunique-identifier
    Metadata:
      aws:cdk:path: CdkHelloWorldStack/HelloWorldFunction/Resource
      aws:asset:path: asset.unique-identifier
      aws:asset:is-bundled: false
      aws:asset:property: Code
  HelloWorldApiunique-identifier:
    Type: AWS::ApiGateway::RestApi
    Properties:
      Name: HelloWorldApi
    Metadata:
      aws:cdk:path: CdkHelloWorldStack/HelloWorldApi/Resource
  HelloWorldApiDeploymentunique-identifier:
    Type: AWS::ApiGateway::Deployment
    Properties:
      Description: Automatically created by the RestApi construct
      RestApiId:
        Ref: HelloWorldApiunique-identifier
    DependsOn:
      - HelloWorldApihelloGETunique-identifier
      - HelloWorldApihellounique-identifier
    Metadata:
      aws:cdk:path: CdkHelloWorldStack/HelloWorldApi/Deployment/Resource
  HelloWorldApiDeploymentStageprod012345ABC:
    Type: AWS::ApiGateway::Stage
    Properties:
      DeploymentId:
        Ref: HelloWorldApiDeploymentunique-identifier
      RestApiId:
        Ref: HelloWorldApiunique-identifier
      StageName: prod
    Metadata:
      aws:cdk:path: CdkHelloWorldStack/HelloWorldApi/DeploymentStage.prod/Resource
  HelloWorldApihellounique-identifier:
    Type: AWS::ApiGateway::Resource
    Properties:
      ParentId:
        Fn::GetAtt:
          - HelloWorldApiunique-identifier
          - RootResourceId
      PathPart: hello
      RestApiId:
        Ref: HelloWorldApiunique-identifier
    Metadata:
      aws:cdk:path: CdkHelloWorldStack/HelloWorldApi/Default/hello/Resource
  HelloWorldApihelloGETApiPermissionCdkHelloWorldStackHelloWorldApiunique-identifier:
    Type: AWS::Lambda::Permission
    Properties:
      Action: lambda:InvokeFunction
      FunctionName:
        Fn::GetAtt:
          - HelloWorldFunctionunique-identifier
          - Arn
      Principal: apigateway.amazonaws.com
      SourceArn:
        Fn::Join:
          - ""
          - - "arn:"
            - Ref: AWS::Partition
            - ":execute-api:"
            - Ref: AWS::Region
            - ":"
            - Ref: AWS::AccountId
            - ":"
            - Ref: HelloWorldApi9E278160
            - /
            - Ref: HelloWorldApiDeploymentStageprodunique-identifier
            - /GET/hello
    Metadata:
      aws:cdk:path: CdkHelloWorldStack/HelloWorldApi/Default/hello/GET/ApiPermission.CdkHelloWorldStackHelloWorldApiunique-identifier.GET..hello
  HelloWorldApihelloGETApiPermissionTestCdkHelloWorldStackHelloWorldApiunique-identifier:
    Type: AWS::Lambda::Permission
    Properties:
      Action: lambda:InvokeFunction
      FunctionName:
        Fn::GetAtt:
          - HelloWorldFunctionunique-identifier
          - Arn
      Principal: apigateway.amazonaws.com
      SourceArn:
        Fn::Join:
          - ""
          - - "arn:"
            - Ref: AWS::Partition
            - ":execute-api:"
            - Ref: AWS::Region
            - ":"
            - Ref: AWS::AccountId
            - ":"
            - Ref: HelloWorldApiunique-identifier
            - /test-invoke-stage/GET/hello
    Metadata:
      aws:cdk:path: CdkHelloWorldStack/HelloWorldApi/Default/hello/GET/ApiPermission.Test.CdkHelloWorldStackHelloWorldApiunique-identifier.GET..hello
  HelloWorldApihelloGETunique-identifier:
    Type: AWS::ApiGateway::Method
    Properties:
      AuthorizationType: NONE
      HttpMethod: GET
      Integration:
        IntegrationHttpMethod: POST
        Type: AWS_PROXY
        Uri:
          Fn::Join:
            - ""
            - - "arn:"
              - Ref: AWS::Partition
              - ":apigateway:"
              - Ref: AWS::Region
              - :lambda:path/2015-03-31/functions/
              - Fn::GetAtt:
                  - HelloWorldFunctionunique-identifier
                  - Arn
              - /invocations
      ResourceId:
        Ref: HelloWorldApihellounique-identifier
      RestApiId:
        Ref: HelloWorldApiunique-identifier
    Metadata:
      aws:cdk:path: CdkHelloWorldStack/HelloWorldApi/Default/hello/GET/Resource
  CDKMetadata:
    Type: AWS::CDK::Metadata
    Properties:
      Analytics: v2:deflate64:unique-identifier
    Metadata:
      aws:cdk:path: CdkHelloWorldStack/CDKMetadata/Default
    Condition: CDKMetadataAvailable
Outputs:
  HelloWorldApiEndpointunique-identifier:
    Value:
      Fn::Join:
        - ""
        - - https://
          - Ref: HelloWorldApiunique-identifier
          - .execute-api.
          - Ref: AWS::Region
          - "."
          - Ref: AWS::URLSuffix
          - /
          - Ref: HelloWorldApiDeploymentStageprodunique-identifier
          - /
Conditions:
  CDKMetadataAvailable:
    Fn::Or:
      - Fn::Or:
          - Fn::Equals:
              - Ref: AWS::Region
              - af-south-1
          - Fn::Equals:
              - Ref: AWS::Region
              - ap-east-1
          - Fn::Equals:
              - Ref: AWS::Region
              - ap-northeast-1
          - Fn::Equals:
              - Ref: AWS::Region
              - ap-northeast-2
          - Fn::Equals:
              - Ref: AWS::Region
              - ap-south-1
          - Fn::Equals:
              - Ref: AWS::Region
              - ap-southeast-1
          - Fn::Equals:
              - Ref: AWS::Region
              - ap-southeast-2
          - Fn::Equals:
              - Ref: AWS::Region
              - ca-central-1
          - Fn::Equals:
              - Ref: AWS::Region
              - cn-north-1
          - Fn::Equals:
              - Ref: AWS::Region
              - cn-northwest-1
      - Fn::Or:
          - Fn::Equals:
              - Ref: AWS::Region
              - eu-central-1
          - Fn::Equals:
              - Ref: AWS::Region
              - eu-north-1
          - Fn::Equals:
              - Ref: AWS::Region
              - eu-south-1
          - Fn::Equals:
              - Ref: AWS::Region
              - eu-west-1
          - Fn::Equals:
              - Ref: AWS::Region
              - eu-west-2
          - Fn::Equals:
              - Ref: AWS::Region
              - eu-west-3
          - Fn::Equals:
              - Ref: AWS::Region
              - il-central-1
          - Fn::Equals:
              - Ref: AWS::Region
              - me-central-1
          - Fn::Equals:
              - Ref: AWS::Region
              - me-south-1
          - Fn::Equals:
              - Ref: AWS::Region
              - sa-east-1
      - Fn::Or:
          - Fn::Equals:
              - Ref: AWS::Region
              - us-east-1
          - Fn::Equals:
              - Ref: AWS::Region
              - us-east-2
          - Fn::Equals:
              - Ref: AWS::Region
              - us-west-1
          - Fn::Equals:
              - Ref: AWS::Region
              - us-west-2
Parameters:
  BootstrapVersion:
    Type: AWS::SSM::Parameter::Value<String>
    Default: /cdk-bootstrap/hnb659fds/version
    Description: Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]
Rules:
  CheckBootstrapVersion:
    Assertions:
      - Assert:
          Fn::Not:
            - Fn::Contains:
                - - "1"
                  - "2"
                  - "3"
                  - "4"
                  - "5"
                - Ref: BootstrapVersion
        AssertDescription: CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI.
```

Al utilizar constructos L2, se definen algunas propiedades para configurar los activos y se utilizan métodos auxiliares para integrarlos entre sí. AWS CDK configura la mayoría de los recursos de AWS CloudFormation y propiedades necesarios para aprovisionar la aplicación.

## Paso 5: implementar la aplicación
<a name="serverless-example-deploy"></a>

En este paso, utilice el comando `cdk deploy` de la CLI de AWS CDK para implementar su aplicación. El AWS CDK funciona con el servicio de AWS CloudFormation para aprovisionar sus recursos.

**importante**  
Debe realizar un arranque único del entorno AWS antes de la implementación. Para obtener instrucciones, consulte [Arranque su entorno para utilizarlo con el AWS CDK](bootstrapping-env.md).

Desde la raíz del proyecto, ejecute lo siguiente. Confirme los cambios, si se le solicita:

```
$ cdk deploy

✨  Synthesis time: 2.44s

...

Do you wish to deploy these changes (y/n)? <y>
```

Cuando la implementación esté completa, la CLI de AWS CDK generará la URL de su punto de conexión. Copie esta URL para el siguiente paso. A continuación, se muestra un ejemplo:

```
...
✅  HelloWorldStack

✨  Deployment time: 45.37s

Outputs:
HelloWorldStack.HelloWorldApiEndpointunique-identifier = https://<api-id>.execute-api.<region>.amazonaws.com/prod/
Stack ARN:
arn:aws:cloudformation:region:account-id:stack/HelloWorldStack/unique-identifier
...
```

## Paso 6: cómo interactuar con su aplicación
<a name="serverless-example-interact"></a>

En este paso, inicie una solicitud GET al punto de conexión de la API y verá el resultado de la función de Lambda.

Localice la URL del punto de conexión del paso anterior y agregue la ruta `/hello`. Luego, mediante el navegador o la línea de comandos, envíe una solicitud GET al punto de conexión. A continuación, se muestra un ejemplo:

```
$ curl https://<api-id>.execute-api.<region>.amazonaws.com/prod/hello
{"message":"Hello World!"}%
```

¡Felicitaciones\$1 Ha creado, implementado e interactuado correctamente con su aplicación a través de AWS CDK.

## Paso 7: cómo eliminar la aplicación
<a name="serverless-example-delete"></a>

En este paso, se utiliza la CLI del AWS CDK para eliminar la aplicación de la nube de AWS.

Para eliminar la aplicación, ejecute `cdk destroy`. Cuando se le indique, confirme su solicitud para eliminar la aplicación:

```
$ cdk destroy
Are you sure you want to delete: CdkHelloWorldStack (y/n)? y
CdkHelloWorldStack: destroying... [1/1]
...
 ✅  CdkHelloWorldStack: destroyed
```

## Solución de problemas
<a name="serverless-example-troubleshooting"></a>

### Error: \$1"message": "Internal server error"\$1%
<a name="serverless-example-trobuleshooting-error1"></a>

Al invocar la función de Lambda implementada, recibe este error. Este puede producirse por varios motivos.

 **Para la resolución de más problemas**   
Utilice la AWS CLI para invocar la función de Lambda.  

1. Modifique el archivo de pila para capturar el valor de salida del nombre de la función de Lambda implementada. A continuación, se muestra un ejemplo:

   ```
   ...
   
   class CdkHelloWorldStack extends Stack {
     constructor(scope, id, props) {
       super(scope, id, props);
   
       // Define the Lambda function resource
       // ...
   
       new CfnOutput(this, 'HelloWorldFunctionName', {
         value: helloWorldFunction.functionName,
         description: 'JavaScript Lambda function'
       });
   
       // Define the API Gateway resource
       // ...
     }
   }
   ```

1. Implemente nuevamente la aplicación. La CLI de AWS CDK mostrará el valor del nombre de la función de Lambda implementada:

   ```
   $ cdk deploy
   
   ✨  Synthesis time: 0.29s
   ...
    ✅  CdkHelloWorldStack
   
   ✨  Deployment time: 20.36s
   
   Outputs:
   ...
   CdkHelloWorldStack.HelloWorldFunctionName = CdkHelloWorldStack-HelloWorldFunctionunique-identifier
   ...
   ```

1. Utilice la AWS CLI para invocar la función de Lambda en la nube de AWS y la respuesta a un archivo de texto:

   ```
   $ aws lambda invoke --function-name CdkHelloWorldStack-HelloWorldFunctionunique-identifier output.txt
   ```

1. Verifique `output.txt` para ver los resultados.  
 **Posible causa: el activo API Gateway está definido de forma incorrecta en el archivo de pila**   
Si `output.txt` muestra una respuesta correcta de la función de Lambda, el problema podría estar relacionado con la forma en que definió la API de REST de API Gateway. La AWS CLI invoca su Lambda directamente, no a través de su punto de conexión. Verifique su código para asegurarse de que coincide con este tutorial. A continuación, vuelva a realizar la implementación.  
 **Posible causa: el activo Lambda está definido incorrectamente en el archivo de pila**   
Si `output.txt` devuelve un error, el problema podría estar relacionado con la forma en que definió la función de Lambda. Verifique su código para asegurarse de que coincide con este tutorial. A continuación, vuelva a realizar la implementación.