

Este é o Guia do desenvolvedor do AWS CDK v2. O CDK v1 antigo entrou em manutenção em 1º de junho de 2022 e encerrou o suporte em 1º de junho de 2023.

As traduções são geradas por tradução automática. Em caso de conflito entre o conteúdo da tradução e da versão original em inglês, a versão em inglês prevalecerá.

# AWS Construções CDK
<a name="constructs"></a>

As construções são os componentes básicos dos aplicativos do AWS Cloud Development Kit (AWS CDK). Uma construção é um componente em seu aplicativo que representa um ou mais AWS CloudFormation recursos e sua configuração. Você compila sua aplicação, parte por parte, importando e configurando constructos.

## Importar e usar constructos
<a name="constructs-import"></a>

Os constructos são classes que você importa para suas aplicações do CDK da [Biblioteca de Constructos da AWS](libraries.md#libraries-construct). Você também pode criar e distribuir seus próprios constructos ou usar constructos criados por desenvolvedores terceirizados.

Os constructos fazem parte do Construct Programming Model (CPM – Modelo de programação de constructo). Eles estão disponíveis para uso com outras ferramentas, como CDK for Terraform (CDKtf), CDK for Kubernetes (CDK8s) e. Projen

Vários terceiros também publicaram construções compatíveis com o AWS CDK. Visite o [Construct Hub](https://constructs.dev/search?q=&cdk=aws-cdk&cdkver=2&offset=0) para explorar o ecossistema de parceiros do AWS CDK Construct.

## Níveis de constructo
<a name="constructs-lib-levels"></a>

As construções da AWS Construct Library são categorizadas em três níveis. Cada nível oferece um nível crescente de abstração. Quanto maior a abstração, mais fácil de configurar, exigindo menos experiência. Quanto menor a abstração, mais personalização está disponível, exigindo mais experiência.<a name="constructs-lib-levels-one"></a>

 **Construções de nível 1 (L1)**   
Os constructos L1, também conhecidos como *recursos do CFN*, são os constructos de nível mais baixo e não oferecem abstração. Cada construção L1 é mapeada diretamente para um único AWS CloudFormation recurso. Com construções L1, você importa uma construção que representa um recurso específico AWS CloudFormation . Em seguida, você define as propriedades do recurso em sua instância de constructo.  
As construções L1 são ótimas para usar quando você está familiarizado AWS CloudFormation e precisa de controle total sobre a definição das propriedades de seus AWS recursos.  
Na AWS Construct Library, as construções L1 são nomeadas começando com`Cfn`, seguidas por um identificador para o AWS CloudFormation recurso que elas representam. Por exemplo, a [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_s3.CfnBucket.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_s3.CfnBucket.html)construção é uma construção L1 que representa um [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_s3.Bucket.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_s3.Bucket.html) AWS CloudFormation recurso.  
Os constructos L1 são gerados a partir da especificação do [recurso do AWS CloudFormation ](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-resource-specification.html). Se um recurso existir em AWS CloudFormation, ele estará disponível no AWS CDK como uma construção L1. Novos recursos ou propriedades podem levar até uma semana para serem disponibilizados na AWS Construct Library. Para obter mais informações, consulte a [referência de tipos de AWS recursos e propriedades](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-template-resource-type-ref.html) no *Guia AWS CloudFormation do usuário*.<a name="constructs-lib-levels-two"></a>

 **Construções de nível 2 (L2)**   
Os constructos L2, também conhecidas como constructos *curados*, são cuidadosamente desenvolvidos pela equipe do CDK e geralmente são o tipo de constructo mais amplamente usado. As construções L2 são mapeadas diretamente para AWS CloudFormation recursos individuais, semelhantes às construções L1. Em comparação com os constructos L1, os constructos L2 fornecem uma abstração de alto nível por meio de uma API intuitiva baseada em intenção. Os constructos L2 incluem configurações de propriedades padrão sensatas, políticas de segurança de práticas recomendadas e geram muito código clichê e lógica de colagem para você.  
Os constructos L2 também fornecem métodos auxiliares para a maioria dos recursos que simplificam e agilizam a definição de propriedades, permissões, interações baseadas em eventos entre recursos e muito mais. Muitos desses recursos também estão disponíveis como blocos de construção independentes chamados [Mixins](mixins.md), que podem ser aplicados às construções L1 e L2 usando o método. `.with()`  
A classe [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_s3.Bucket.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_s3.Bucket.html) é um exemplo de um constructo L2 para um recurso de bucket do Amazon Simple Storage Service (Amazon S3).  
A AWS Construct Library contém construções L2 que são designadas como estáveis e prontas para uso em produção. Para constructos L2 em desenvolvimento, eles são designados como experimentais e oferecidos em um módulo separado.<a name="constructs-lib-levels-three"></a>

 **Construções de nível 3 (L3)**   
Os constructos L3, também conhecidos como *padrões*, são o nível mais alto de abstração. Cada constructo L3 pode conter uma coleção de recursos que são configurados para trabalhar juntos para realizar uma tarefa ou serviço específico em sua aplicação. As construções L3 são usadas para criar AWS arquiteturas inteiras para casos de uso específicos em seu aplicativo.  
Para fornecer projetos de sistema completos ou partes substanciais de um sistema maior, os constructos L3 oferecem configurações de propriedades padrão opinativas. Eles são construídos em torno de uma abordagem específica para resolver um problema e fornecer uma solução. Com constructos L3, você pode criar e configurar vários recursos rapidamente, com a menor quantidade de entrada e código.  
A [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_ecs_patterns.ApplicationLoadBalancedFargateService.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_ecs_patterns.ApplicationLoadBalancedFargateService.html)classe é um exemplo de uma construção L3 que representa um serviço AWS Fargate executado em um cluster do Amazon Elastic Container Service (Amazon ECS) e liderado por um balanceador de carga de aplicativos.  
Semelhantes às construções L2, as construções L3 que estão prontas para uso em produção estão incluídas na Construct Library. AWS Os que estão em desenvolvimento são oferecidos em módulos separados.

## Definição de constructos
<a name="constructs-define"></a>

### Composição
<a name="constructs-composition"></a>

 A *composição* é o padrão chave para definir abstrações de alto nível por meio de constructos. Um constructo de alto nível pode ser composto a partir de qualquer número de constructos de nível inferior. De uma perspectiva de baixo para cima, você usa construções para organizar os AWS recursos individuais que deseja implantar. Você usa quaisquer abstrações que sejam convenientes para seu propósito, com quantos níveis precisar.

Com a composição, você define componentes reutilizáveis e os compartilha como qualquer outro código. Por exemplo, uma equipe pode definir um constructo que implemente as práticas recomendadas da empresa em uma tabela do Amazon DynamoDB, incluindo backup, replicação global, escalabilidade automática e monitoramento. A equipe pode compartilhar o constructo internamente com outras equipes ou publicamente.

As equipes podem usar constructos como qualquer outro pacote de biblioteca. Quando a biblioteca é atualizada, os desenvolvedores têm acesso às melhorias e correções de erros da nova versão, de forma semelhante a qualquer outra biblioteca de código.

### Inicialização
<a name="constructs-init"></a>

As estruturas são implementadas em classes que estendem a classe base no [https://docs.aws.amazon.com/cdk/api/v2/docs/constructs.Construct.html](https://docs.aws.amazon.com/cdk/api/v2/docs/constructs.Construct.html). Você define um constructo instanciando a classe. Todas as estruturas usam três parâmetros ao serem inicializadas:
+  **escopo**: o pai ou proprietário do constructo. Pode ser uma pilha ou outro constructo. O escopo determina o lugar do constructo na [árvore de constructos](apps.md#apps-tree). Em geral, é necessário passar `this` (`self` no Python), que representa o objeto atual, para o escopo.
+  **id**: um [identificador](identifiers.md) que deve ser exclusivo dentro desse escopo. O identificador serve como um namespace para tudo o que está definido no constructo. Ele é usado para gerar identificadores exclusivos, como [nomes de recursos](resources.md#resources-physical-names) e AWS CloudFormation lógicos IDs.

  Os identificadores só precisam ser exclusivos dentro de um escopo. Ele permite que você instancie e reutilize constructos sem se preocupar com os constructos e identificadores que eles possam conter, além de permitir a composição de constructos em abstrações de alto nível. Além disso, os escopos possibilitam a referência a grupos de constructos de uma só vez. Os exemplos incluem a [marcação](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Tag.html) ou a especificação de onde os constructos serão implantados.
+  **props**: um conjunto de propriedades ou argumentos de palavras-chave, dependendo da linguagem, que definem a configuração inicial do constructo. Constructos de nível superior fornecem mais padrões e, se todos os elementos prop forem opcionais, será possível omitir completamente o parâmetro props.

### Configuração
<a name="constructs-config"></a>

A maioria das construções aceita `props` como terceiro argumento (ou, em Python, argumentos de palavra-chave) name/value uma coleção que define a configuração da construção. O exemplo a seguir define um bucket com criptografia do AWS Key Management Service (AWS KMS) e hospedagem estática de sites ativados. Como não especifica explicitamente uma chave de criptografia, o constructo do `Bucket` define uma nova `kms.Key` e a associa ao bucket.

**Example**  

```
new s3.Bucket(this, 'MyEncryptedBucket', {
  encryption: s3.BucketEncryption.KMS,
  websiteIndexDocument: 'index.html'
});
```

```
new s3.Bucket(this, 'MyEncryptedBucket', {
  encryption: s3.BucketEncryption.KMS,
  websiteIndexDocument: 'index.html'
});
```

```
s3.Bucket(self, "MyEncryptedBucket", encryption=s3.BucketEncryption.KMS,
    website_index_document="index.html")
```

```
Bucket.Builder.create(this, "MyEncryptedBucket")
        .encryption(BucketEncryption.KMS_MANAGED)
        .websiteIndexDocument("index.html").build();
```

```
new Bucket(this, "MyEncryptedBucket", new BucketProps
{
    Encryption = BucketEncryption.KMS_MANAGED,
    WebsiteIndexDocument = "index.html"
});
```

```
	awss3.NewBucket(stack, jsii.String("MyEncryptedBucket"), &awss3.BucketProps{
		Encryption: awss3.BucketEncryption_KMS,
		WebsiteIndexDocument: jsii.String("index.html"),
	})
```

### Interagir com constructos
<a name="constructs-interact"></a>

Os constructos são implementados em classes que estendem a classe de [constructo](https://docs.aws.amazon.com/cdk/api/v2/docs/constructs.Construct.html) de base. Depois de instanciar um constructo, o objeto do constructo expõe um conjunto de métodos e propriedades que permitem que você interaja com o constructo e o transmita como referência para outras partes do sistema.

A estrutura AWS CDK não impõe nenhuma restrição às APIs construções. Os autores podem definir qualquer API que quiserem. No entanto, as AWS construções incluídas na AWS Construct Library, por exemplo`s3.Bucket`, seguem diretrizes e padrões comuns. Isso proporciona uma experiência consistente em todos os AWS recursos.

A maioria das AWS construções tem um conjunto de métodos de [concessão](permissions.md#permissions-grants) que você pode usar para conceder permissões de AWS Identity and Access Management (IAM) sobre essa construção a um diretor. O exemplo a seguir concede a permissão `data-science` ao grupo do IAM para ler a partir do bucket `raw-data` do Amazon S3.

**Example**  

```
const rawData = new s3.Bucket(this, 'raw-data');
const dataScience = new iam.Group(this, 'data-science');
rawData.grants.read(dataScience);
```

```
const rawData = new s3.Bucket(this, 'raw-data');
const dataScience = new iam.Group(this, 'data-science');
rawData.grants.read(dataScience);
```

```
raw_data = s3.Bucket(self, 'raw-data')
data_science = iam.Group(self, 'data-science')
raw_data.grants.read(data_science)
```

```
Bucket rawData = new Bucket(this, "raw-data");
Group dataScience = new Group(this, "data-science");
rawData.getGrants().read(dataScience);
```

```
var rawData = new Bucket(this, "raw-data");
var dataScience = new Group(this, "data-science");
rawData.Grants.Read(dataScience);
```

```
	rawData := awss3.NewBucket(stack, jsii.String("raw-data"), nil)
	dataScience := awsiam.NewGroup(stack, jsii.String("data-science"), nil)
	rawData.Grants().Read(dataScience, nil)
```

Outro padrão comum é que AWS as construções definam um dos atributos do recurso a partir de dados fornecidos em outro lugar. Os atributos podem incluir nomes de recursos da Amazon (ARNs), nomes ou URLs.

O código a seguir define uma função AWS Lambda e a associa a uma fila do Amazon Simple Queue Service (Amazon SQS) por meio da URL da fila em uma variável de ambiente.

**Example**  

```
const jobsQueue = new sqs.Queue(this, 'jobs');
const createJobLambda = new lambda.Function(this, 'create-job', {
  runtime: lambda.Runtime.NODEJS_18_X,
  handler: 'index.handler',
  code: lambda.Code.fromAsset('./create-job-lambda-code'),
  environment: {
    QUEUE_URL: jobsQueue.queueUrl
  }
});
```

```
const jobsQueue = new sqs.Queue(this, 'jobs');
const createJobLambda = new lambda.Function(this, 'create-job', {
  runtime: lambda.Runtime.NODEJS_18_X,
  handler: 'index.handler',
  code: lambda.Code.fromAsset('./create-job-lambda-code'),
  environment: {
    QUEUE_URL: jobsQueue.queueUrl
  }
});
```

```
jobs_queue = sqs.Queue(self, "jobs")
create_job_lambda = lambda_.Function(self, "create-job",
    runtime=lambda_.Runtime.NODEJS_18_X,
    handler="index.handler",
    code=lambda_.Code.from_asset("./create-job-lambda-code"),
    environment=dict(
        QUEUE_URL=jobs_queue.queue_url
    )
)
```

```
final Queue jobsQueue = new Queue(this, "jobs");
Function createJobLambda = Function.Builder.create(this, "create-job")
                .handler("index.handler")
                .code(Code.fromAsset("./create-job-lambda-code"))
                .environment(java.util.Map.of(   // Map.of is Java 9 or later
                    "QUEUE_URL", jobsQueue.getQueueUrl()))
                .build();
```

```
var jobsQueue = new Queue(this, "jobs");
var createJobLambda = new Function(this, "create-job", new FunctionProps
{
    Runtime = Runtime.NODEJS_18_X,
    Handler = "index.handler",
    Code = Code.FromAsset(@".\create-job-lambda-code"),
    Environment = new Dictionary<string, string>
    {
        ["QUEUE_URL"] = jobsQueue.QueueUrl
    }
});
```

```
	createJobLambda := awslambda.NewFunction(stack, jsii.String("create-job"), &awslambda.FunctionProps{
		Runtime: awslambda.Runtime_NODEJS_18_X(),
		Handler: jsii.String("index.handler"),
		Code:    awslambda.Code_FromAsset(jsii.String(".\\create-job-lambda-code"), nil),
		Environment: &map[string]*string{
			"QUEUE_URL": jsii.String(*jobsQueue.QueueUrl()),
		},
	})
```

Para obter informações sobre os padrões de API mais comuns na AWS Construct Library, consulte [Resources and the AWS CDK](resources.md).

### Adicione recursos com o Mixins
<a name="constructs-mixins"></a>

Os mixins são recursos combináveis que você pode aplicar a qualquer construção usando o método. `.with()` Os mixins permitem que você adicione funcionalidade às construções L1 e L2 sem precisar usar uma construção diferente ou escrever código de baixo nível.

Por exemplo, você pode habilitar o controle de versão e bloquear o acesso público em um bucket do Amazon S3, seja ele L1 ou `CfnBucket` L2: `Bucket`

**Example**  

```
import * as cdk from 'aws-cdk-lib';
import * as s3 from 'aws-cdk-lib/aws-s3';

// Apply mixins to an L1 construct
new s3.CfnBucket(this, 'MyBucket')
  .with(new s3.mixins.BucketVersioning())
  .with(new s3.mixins.BucketBlockPublicAccess());

// Apply mixins to an L2 construct
new s3.Bucket(this, 'MyL2Bucket', { removalPolicy: cdk.RemovalPolicy.DESTROY })
  .with(new s3.mixins.BucketAutoDeleteObjects());
```

```
const cdk = require('aws-cdk-lib');
const s3 = require('aws-cdk-lib/aws-s3');

// Apply mixins to an L1 construct
new s3.CfnBucket(this, 'MyBucket')
  .with(new s3.mixins.BucketVersioning())
  .with(new s3.mixins.BucketBlockPublicAccess());

// Apply mixins to an L2 construct
new s3.Bucket(this, 'MyL2Bucket', { removalPolicy: cdk.RemovalPolicy.DESTROY })
  .with(new s3.mixins.BucketAutoDeleteObjects());
```

```
import aws_cdk as cdk
import aws_cdk.aws_s3 as s3

# Apply mixins to an L1 construct
s3.CfnBucket(self, "MyBucket") \
    .with_(s3.mixins.BucketVersioning()) \
    .with_(s3.mixins.BucketBlockPublicAccess())

# Apply mixins to an L2 construct
s3.Bucket(self, "MyL2Bucket", removal_policy=cdk.RemovalPolicy.DESTROY) \
    .with_(s3.mixins.BucketAutoDeleteObjects())
```

```
import software.amazon.awscdk.*;
import software.amazon.awscdk.services.s3.*;

// Apply mixins to an L1 construct
CfnBucket bucket = new CfnBucket(this, "MyBucket");
bucket.with(new BucketVersioning());
bucket.with(new BucketBlockPublicAccess());

// Apply mixins to an L2 construct
Bucket l2Bucket = Bucket.Builder.create(this, "MyL2Bucket")
        .removalPolicy(RemovalPolicy.DESTROY)
        .build();
l2Bucket.with(new BucketAutoDeleteObjects());
```

```
using Amazon.CDK;
using Amazon.CDK.AWS.S3;

// Apply mixins to an L1 construct
var bucket = new CfnBucket(this, "MyBucket");
bucket.With(new BucketVersioning());
bucket.With(new BucketBlockPublicAccess());

// Apply mixins to an L2 construct
var l2Bucket = new Bucket(this, "MyL2Bucket", new BucketProps
{
    RemovalPolicy = RemovalPolicy.DESTROY
});
l2Bucket.With(new BucketAutoDeleteObjects());
```

```
bucket := awss3.NewCfnBucket(stack, jsii.String("MyBucket"), nil)
bucket.With(awss3.NewBucketVersioning())
bucket.With(awss3.NewBucketBlockPublicAccess())

l2Bucket := awss3.NewBucket(stack, jsii.String("MyL2Bucket"), &awss3.BucketProps{
    RemovalPolicy: awscdk.RemovalPolicy_DESTROY,
})
l2Bucket.With(awss3.NewBucketAutoDeleteObjects())
```

Os mixins estão disponíveis por meio do `mixins` namespace de cada módulo de serviço (por exemplo,). `s3.mixins` Cada mixin tem como alvo um tipo de recurso específico e tem o nome desse recurso. Quando você aplica um mixin a uma construção L2, ele se aplica automaticamente ao recurso L1 subjacente.

Para obter mais informações sobre Mixins, consulte [Mixins](mixins.md).

### O constructo da aplicação e da pilha
<a name="constructs-apps-stacks"></a>

As [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Stack.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Stack.html)classes [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.App.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.App.html)e da AWS Construct Library são construções exclusivas. Em comparação com outras construções, elas não configuram AWS recursos sozinhas. Em vez disso, eles usados para fornecer contexto para seus outros constructos. Todas as construções que representam AWS recursos devem ser definidas, direta ou indiretamente, dentro do escopo de uma `Stack` construção. `Stack`construções são definidas dentro do escopo de uma `App` construção.

Para saber mais sobre as aplicações do CDK, consulte [Aplicações do AWS CDK](apps.md). Para saber mais sobre pilhas de CDK, consulte [Introdução às pilhas de AWS CDK](stacks.md).

O exemplo a seguir define uma aplicação com uma única pilha. Dentro da pilha, um constructo L2 é usado para configurar um recurso de bucket do Amazon S3.

**Example**  

```
import { App, Stack, StackProps } from 'aws-cdk-lib';
import * as s3 from 'aws-cdk-lib/aws-s3';

class HelloCdkStack extends Stack {
  constructor(scope: App, id: string, props?: StackProps) {
    super(scope, id, props);

    new s3.Bucket(this, 'MyFirstBucket', {
      versioned: true
    });
  }
}

const app = new App();
new HelloCdkStack(app, "HelloCdkStack");
```

```
const { App , Stack } = require('aws-cdk-lib');
const s3 = require('aws-cdk-lib/aws-s3');

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

    new s3.Bucket(this, 'MyFirstBucket', {
      versioned: true
    });
  }
}

const app = new App();
new HelloCdkStack(app, "HelloCdkStack");
```

```
from aws_cdk import App, Stack
import aws_cdk.aws_s3 as s3
from constructs import Construct

class HelloCdkStack(Stack):

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

        s3.Bucket(self, "MyFirstBucket", versioned=True)

app = App()
HelloCdkStack(app, "HelloCdkStack")
```
Pilha definida no arquivo `HelloCdkStack.java`:  

```
import software.constructs.Construct;
import software.amazon.awscdk.Stack;
import software.amazon.awscdk.StackProps;
import software.amazon.awscdk.services.s3.*;

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

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

        Bucket.Builder.create(this, "MyFirstBucket")
            .versioned(true).build();
    }
}
```
Aplicação definida no arquivo `HelloCdkApp.java`:  

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

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

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

        app.synth();
    }
}
```

```
using Amazon.CDK;
using Amazon.CDK.AWS.S3;

namespace HelloCdkApp
{
    internal static class Program
    {
        public static void Main(string[] args)
        {
            var app = new App();
            new HelloCdkStack(app, "HelloCdkStack");
            app.Synth();
        }
    }

    public class HelloCdkStack : Stack
    {
        public HelloCdkStack(Construct scope, string id, IStackProps props=null) : base(scope, id, props)
        {
            new Bucket(this, "MyFirstBucket", new BucketProps { Versioned = true });
        }
    }
}
```

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

	awss3.NewBucket(stack, jsii.String("MyFirstBucket"), &awss3.BucketProps{
		Versioned: jsii.Bool(true),
	})

	return stack
}
```

## Trabalhar com constructos
<a name="constructs-work"></a>

### Trabalhar com constructos L1
<a name="constructs-l1-using"></a>

L1 constrói mapas diretamente para recursos individuais AWS CloudFormation . Você mesmo deve fornecer a configuração necessária para o recurso.

Neste exemplo, criamos um objeto de `bucket` usando o constructo L1 `CfnBucket`:

**Example**  

```
const bucket = new s3.CfnBucket(this, "amzn-s3-demo-bucket", {
  bucketName: "amzn-s3-demo-bucket"
});
```

```
const bucket = new s3.CfnBucket(this, "amzn-s3-demo-bucket", {
  bucketName: "amzn-s3-demo-bucket"
});
```

```
bucket = s3.CfnBucket(self, "amzn-s3-demo-bucket", bucket_name="amzn-s3-demo-bucket")
```

```
CfnBucket bucket = new CfnBucket.Builder().bucketName("amzn-s3-demo-bucket").build();
```

```
var bucket = new CfnBucket(this, "amzn-s3-demo-bucket", new CfnBucketProps
{
    BucketName= "amzn-s3-demo-bucket"
});
```

```
	awss3.NewCfnBucket(stack, jsii.String("amzn-s3-demo-bucket"), &awss3.CfnBucketProps{
		BucketName: jsii.String("amzn-s3-demo-bucket"),
	})
```

Propriedades de constructos que não sejam simples booleanos, strings, números ou contêineres são tratadas de forma diferente nas linguagens com suporte.

**Example**  

```
const bucket = new s3.CfnBucket(this, "amzn-s3-demo-bucket", {
  bucketName: "amzn-s3-demo-bucket",
  corsConfiguration: {
    corsRules: [{
          allowedOrigins: ["*"],
          allowedMethods: ["GET"]
    }]
  }
});
```

```
const bucket = new s3.CfnBucket(this, "amzn-s3-demo-bucket", {
  bucketName: "amzn-s3-demo-bucket",
  corsConfiguration: {
    corsRules: [{
          allowedOrigins: ["*"],
          allowedMethods: ["GET"]
    }]
  }
});
```
Em Python, essas propriedades são representadas por tipos definidos como classes internas do constructo L1. Por exemplo, a propriedade opcional `cors_configuration` de um `CfnBucket` requer um wrapper do tipo `CfnBucket.CorsConfigurationProperty`. Aqui estamos definindo `cors_configuration` em uma instância `CfnBucket`.  

```
bucket = CfnBucket(self, "amzn-s3-demo-bucket", bucket_name="amzn-s3-demo-bucket",
    cors_configuration=CfnBucket.CorsConfigurationProperty(
        cors_rules=[CfnBucket.CorsRuleProperty(
            allowed_origins=["*"],
            allowed_methods=["GET"]
        )]
    )
)
```
Em Java, essas propriedades são representadas por tipos definidos como classes internas do constructo L1. Por exemplo, a propriedade opcional `corsConfiguration` de um `CfnBucket` requer um wrapper do tipo `CfnBucket.CorsConfigurationProperty`. Aqui estamos definindo `corsConfiguration` em uma instância `CfnBucket`.  

```
CfnBucket bucket = CfnBucket.Builder.create(this, "amzn-s3-demo-bucket")
                        .bucketName("amzn-s3-demo-bucket")
                        .corsConfiguration(new CfnBucket.CorsConfigurationProperty.Builder()
                            .corsRules(Arrays.asList(new CfnBucket.CorsRuleProperty.Builder()
                                .allowedOrigins(Arrays.asList("*"))
                                .allowedMethods(Arrays.asList("GET"))
                                .build()))
                            .build())
                        .build();
```
Em C\$1, essas propriedades são representadas por tipos definidos como classes internas do constructo L1. Por exemplo, a propriedade opcional `CorsConfiguration` de um `CfnBucket` requer um wrapper do tipo `CfnBucket.CorsConfigurationProperty`. Aqui estamos definindo `CorsConfiguration` em uma instância `CfnBucket`.  

```
var bucket = new CfnBucket(this, "amzn-s3-demo-bucket", new CfnBucketProps
{
    BucketName = "amzn-s3-demo-bucket",
    CorsConfiguration = new CfnBucket.CorsConfigurationProperty
    {
        CorsRules = new object[] {
            new CfnBucket.CorsRuleProperty
            {
                AllowedOrigins = new string[] { "*" },
                AllowedMethods = new string[] { "GET" },
            }
        }
    }
});
```
Em Go, esses tipos são nomeados usando o nome do constructo L1, um sublinhado e o nome da propriedade. Por exemplo, a propriedade opcional `CorsConfiguration` de um `CfnBucket` requer um wrapper do tipo `CfnBucket_CorsConfigurationProperty`. Aqui estamos definindo `CorsConfiguration` em uma instância `CfnBucket`.  

```
	awss3.NewCfnBucket(stack, jsii.String("amzn-s3-demo-bucket"), &awss3.CfnBucketProps{
		BucketName: jsii.String("amzn-s3-demo-bucket"),
		CorsConfiguration: &awss3.CfnBucket_CorsConfigurationProperty{
			CorsRules: []awss3.CorsRule{
				awss3.CorsRule{
					AllowedOrigins: jsii.Strings("*"),
					AllowedMethods: &[]awss3.HttpMethods{"GET"},
				},
			},
		},
	})
```

**Importante**  
Você não pode usar tipos de propriedade L2 com constructos L1 ou vice-versa. Ao trabalhar com constructos L1, sempre use os tipos definidos para o constructo L1 que você estiver usando. Não use tipos de outros constructos L1 (alguns podem ter o mesmo nome, mas não são do mesmo tipo).  
Algumas de nossas referências de API específicas da linguagem atualmente têm erros nos caminhos para os tipos de propriedades L1 ou não documentam essas classes. Esperamos corrigir isso em breve. Enquanto isso, lembre-se de que esses tipos são sempre classes internas do constructo L1 com o qual são usados.

#### Referenciando recursos de outras construções
<a name="constructs-resource-references"></a>

Ao configurar propriedades de construção que fazem referência a outros recursos da AWS, você tem duas opções equivalentes:
+  **Referências de string**: passe valores de string explícitos ARNs, como nomes ou outros identificadores de recursos
+  **Referências de objetos**: passe objetos de construção diretamente. Isso evita a necessidade de determinar qual tipo de identificador uma propriedade espera — o CDK trata disso para você.

##### Usando referências de string
<a name="_using_string_references"></a>

Você sempre pode transmitir valores de string explícitos ARNs, como nomes ou outros identificadores de recursos. Essa abordagem funciona para todas as propriedades e é necessária para propriedades aninhadas em objetos complexos.

O exemplo a seguir cria uma função Lambda usando uma construção L1 (`CfnFunction`) com uma função definida usando uma construção L2 (). `Role` O ARN da função é passado para a `role` propriedade:

**Example**  

```
const role = new iam.Role(this, 'MyRole', {
  assumedBy: new iam.ServicePrincipal('lambda.amazonaws.com'),
  managedPolicies: [
    iam.ManagedPolicy.fromAwsManagedPolicyName(
      'service-role/AWSLambdaBasicExecutionRole'
    ),
  ],
});

const myFunction = new lambda.CfnFunction(this, 'HelloWorldFunction', {
  runtime: 'nodejs24.x',
  role: role.roleArn, // Pass the ARN string explicitly
  handler: 'index.handler',
  code: {
    zipFile: `
    exports.handler = async function(event) {
      return {
        statusCode: 200,
        body: JSON.stringify('Hello World!'),
      };
    };
  `}
});
```

```
const role = new iam.Role(this, 'MyRole', {
  assumedBy: new iam.ServicePrincipal('lambda.amazonaws.com'),
  managedPolicies: [
    iam.ManagedPolicy.fromAwsManagedPolicyName(
      'service-role/AWSLambdaBasicExecutionRole'
    )
  ]
});

const myFunction = new lambda.CfnFunction(this, "HelloWorldFunction", {
  runtime: 'nodejs24.x',
  role: role.roleArn, // Pass the ARN string explicitly
  handler: 'index.handler',
  code: {
    zipFile: `
    exports.handler = async function(event) {
      return {
        statusCode: 200,
        body: JSON.stringify('Hello World!'),
      };
    };
  `}
});
```

```
role = iam.Role(self, "MyRole",
    assumed_by=iam.ServicePrincipal("lambda.amazonaws.com"),
    managed_policies=[
        iam.ManagedPolicy.from_aws_managed_policy_name(
            "service-role/AWSLambdaBasicExecutionRole"
        )
    ]
)

my_function = _lambda.CfnFunction(self, "HelloWorldFunction",
    runtime="nodejs24.x",
    role=role.role_arn,  # Pass the ARN string explicitly
    handler="index.handler",
    code=_lambda.CfnFunction.CodeProperty(
        zip_file=
        """
        exports.handler = async function(event) {
          return {
            statusCode: 200,
            body: JSON.stringify('Hello World!'),
          };
        };
        """
    )
)
```

```
Role role = Role.Builder.create(this, "MyRole")
    .assumedBy(new ServicePrincipal("lambda.amazonaws.com"))
    .managedPolicies(Arrays.asList(
        ManagedPolicy.fromAwsManagedPolicyName(
            "service-role/AWSLambdaBasicExecutionRole"
        )
    ))
    .build();

CfnFunction myFunction = CfnFunction.Builder.create(this, "HelloWorldFunction")
    .runtime("nodejs24.x")
    .role(role.getRoleArn())  // Pass the ARN string explicitly
    .handler("index.handler")
    .code(CfnFunction.CodeProperty.builder()
        .zipFile(
            "exports.handler = async function(event) {" +
            "  return {" +
            "    statusCode: 200," +
            "    body: JSON.stringify('Hello World!')," +
            "  };" +
            "};")
        .build())
    .build();
```

```
var role = new Role(this, "MyRole", new RoleProps
{
    AssumedBy = new ServicePrincipal("lambda.amazonaws.com"),
    ManagedPolicies = new[]
    {
        ManagedPolicy.FromAwsManagedPolicyName(
            "service-role/AWSLambdaBasicExecutionRole"
        )
    }
});

var myFunction = new CfnFunction(this, "HelloWorldFunction", new CfnFunctionProps
{
    Runtime = "nodejs24.x",
    Role = role.RoleArn,  // Pass the ARN string explicitly
    Handler = "index.handler",
    Code = new CfnFunction.CodeProperty
    {
        ZipFile = @"
        exports.handler = async function(event) {
          return {
            statusCode: 200,
            body: JSON.stringify('Hello World!'),
          };
        };
        "
    }
});
```

```
role := awsiam.NewRole(stack, jsii.String("MyRole"), &awsiam.RoleProps{
	AssumedBy: awsiam.NewServicePrincipal(jsii.String("lambda.amazonaws.com"), nil),
	ManagedPolicies: &[]awsiam.IManagedPolicy{
		awsiam.ManagedPolicy_FromAwsManagedPolicyName(jsii.String("service-role/AWSLambdaBasicExecutionRole")),
	},
})

myFunction := awslambda.NewCfnFunction(stack, jsii.String("HelloWorldFunction"), &awslambda.CfnFunctionProps{
	Runtime: jsii.String("nodejs24.x"),
	Role:    role.RoleArn(), // Pass the ARN string explicitly
	Handler: jsii.String("index.handler"),
	Code: &awslambda.CfnFunction_CodeProperty{
		ZipFile: jsii.String(`
		exports.handler = async function(event) {
		  return {
		    statusCode: 200,
		    body: JSON.stringify('Hello World!'),
		  };
		};
		`),
	},
})
```

##### Usando referências de objetos
<a name="_using_object_references"></a>

Para propriedades selecionadas, você pode passar objetos de construção diretamente em vez de extrair seus atributos manualmente. Support para referências de objetos varia de acordo com a propriedade e pode se expandir com o tempo à medida que novas propriedades são adicionadas.

Quando você passa uma referência de objeto na construção`props`, o CDK a resolve para o valor de string apropriado (como um ARN, nome ou outro identificador). Se você acessar posteriormente a propriedade correspondente na instância de construção, verá esse valor de string resolvido, não a referência original do objeto.

As referências a objetos funcionam somente para propriedades de nível superior de construções. Propriedades aninhadas em objetos complexos exigem valores de string explícitos.

O exemplo a seguir mostra a mesma função Lambda, mas usando o objeto de função em vez da string ARN da função:

**Example**  

```
const role = new iam.Role(this, 'MyRole', {
  assumedBy: new iam.ServicePrincipal('lambda.amazonaws.com'),
  managedPolicies: [
    iam.ManagedPolicy.fromAwsManagedPolicyName(
      'service-role/AWSLambdaBasicExecutionRole'
    ),
  ],
});

const myFunction = new lambda.CfnFunction(this, 'HelloWorldFunction', {
  runtime: 'nodejs24.x',
  role: role, // CDK resolves to role ARN automatically
  handler: 'index.handler',
  code: {
    zipFile: `
    exports.handler = async function(event) {
      return {
        statusCode: 200,
        body: JSON.stringify('Hello World!'),
      };
    };
  `}
});

// After creation, myFunction.role contains the resolved ARN string
```

```
const role = new iam.Role(this, 'MyRole', {
  assumedBy: new iam.ServicePrincipal('lambda.amazonaws.com'),
  managedPolicies: [
    iam.ManagedPolicy.fromAwsManagedPolicyName(
      'service-role/AWSLambdaBasicExecutionRole'
    )
  ]
});

const myFunction = new lambda.CfnFunction(this, "HelloWorldFunction", {
  runtime: 'nodejs24.x',
  role: role, // CDK resolves to role ARN automatically
  handler: 'index.handler',
  code: {
    zipFile: `
    exports.handler = async function(event) {
      return {
        statusCode: 200,
        body: JSON.stringify('Hello World!'),
      };
    };
  `}
});

// After creation, myFunction.role contains the resolved ARN string
```

```
role = iam.Role(self, "MyRole",
    assumed_by=iam.ServicePrincipal("lambda.amazonaws.com"),
    managed_policies=[
        iam.ManagedPolicy.from_aws_managed_policy_name(
            "service-role/AWSLambdaBasicExecutionRole"
        )
    ]
)

my_function = _lambda.CfnFunction(self, "HelloWorldFunction",
    runtime="nodejs24.x",
    role=role,  # CDK resolves to role ARN automatically
    handler="index.handler",
    code=_lambda.CfnFunction.CodeProperty(
        zip_file=
        """
        exports.handler = async function(event) {
          return {
            statusCode: 200,
            body: JSON.stringify('Hello World!'),
          };
        };
        """
    )
)

# After creation, my_function.role contains the resolved ARN string
```

```
Role role = Role.Builder.create(this, "MyRole")
    .assumedBy(new ServicePrincipal("lambda.amazonaws.com"))
    .managedPolicies(Arrays.asList(
        ManagedPolicy.fromAwsManagedPolicyName(
            "service-role/AWSLambdaBasicExecutionRole"
        )
    ))
    .build();

CfnFunction myFunction = CfnFunction.Builder.create(this, "HelloWorldFunction")
    .runtime("nodejs24.x")
    .role(role)  // CDK resolves to role ARN automatically
    .handler("index.handler")
    .code(CfnFunction.CodeProperty.builder()
        .zipFile(
            "exports.handler = async function(event) {" +
            "  return {" +
            "    statusCode: 200," +
            "    body: JSON.stringify('Hello World!')," +
            "  };" +
            "};")
        .build())
    .build();

// After creation, myFunction.getRole() contains the resolved ARN string
```

```
var role = new Role(this, "MyRole", new RoleProps
{
    AssumedBy = new ServicePrincipal("lambda.amazonaws.com"),
    ManagedPolicies = new[]
    {
        ManagedPolicy.FromAwsManagedPolicyName(
            "service-role/AWSLambdaBasicExecutionRole"
        )
    }
});

var myFunction = new CfnFunction(this, "HelloWorldFunction", new CfnFunctionProps
{
    Runtime = "nodejs24.x",
    Role = role,  // CDK resolves to role ARN automatically
    Handler = "index.handler",
    Code = new CfnFunction.CodeProperty
    {
        ZipFile = @"
        exports.handler = async function(event) {
          return {
            statusCode: 200,
            body: JSON.stringify('Hello World!'),
          };
        };
        "
    }
});

// After creation, myFunction.Role contains the resolved ARN string
```

```
role := awsiam.NewRole(stack, jsii.String("MyRole"), &awsiam.RoleProps{
	AssumedBy: awsiam.NewServicePrincipal(jsii.String("lambda.amazonaws.com"), nil),
	ManagedPolicies: &[]awsiam.IManagedPolicy{
		awsiam.ManagedPolicy_FromAwsManagedPolicyName(jsii.String("service-role/AWSLambdaBasicExecutionRole")),
	},
})

myFunction := awslambda.NewCfnFunction(stack, jsii.String("HelloWorldFunction"), &awslambda.CfnFunctionProps{
	Runtime: jsii.String("nodejs24.x"),
	Role:    role, // CDK resolves to role ARN automatically
	Handler: jsii.String("index.handler"),
	Code: &awslambda.CfnFunction_CodeProperty{
		ZipFile: jsii.String(`
		exports.handler = async function(event) {
		  return {
		    statusCode: 200,
		    body: JSON.stringify('Hello World!'),
		  };
		};
		`),
	},
})

// After creation, *myFunction.Role() contains the resolved ARN string
```

### Trabalhar com constructos L2
<a name="constructs-using"></a>

No exemplo a seguir, definimos um bucket do Amazon S3 criando um objeto a partir do constructo L2 do [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_s3.Bucket.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_s3.Bucket.html):

**Example**  

```
import * as s3 from 'aws-cdk-lib/aws-s3';

// "this" is HelloCdkStack
new s3.Bucket(this, 'MyFirstBucket', {
  versioned: true
});
```

```
const s3 = require('aws-cdk-lib/aws-s3');

// "this" is HelloCdkStack
new s3.Bucket(this, 'MyFirstBucket', {
  versioned: true
});
```

```
import aws_cdk.aws_s3 as s3

# "self" is HelloCdkStack
s3.Bucket(self, "MyFirstBucket", versioned=True)
```

```
import software.amazon.awscdk.services.s3.*;

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

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

        Bucket.Builder.create(this, "MyFirstBucket")
                .versioned(true).build();
    }
}
```

```
using Amazon.CDK.AWS.S3;

// "this" is HelloCdkStack
new Bucket(this, "MyFirstBucket", new BucketProps
{
    Versioned = true
});
```

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

// stack is HelloCdkStack
awss3.NewBucket(stack, jsii.String("MyFirstBucket"), &awss3.BucketProps{
		Versioned: jsii.Bool(true),
	})
```

 `MyFirstBucket`não é o nome do bucket que AWS CloudFormation cria. É um identificador lógico fornecido ao novo constructo dentro do contexto da sua aplicação do CDK. O valor [PhysicalName](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Resource.html#physicalname) será usado para nomear o AWS CloudFormation recurso.

## Trabalhar com constructos de terceiros
<a name="constructs-work-third"></a>

 O [Construct Hub](https://constructs.dev/search?q=&cdk=aws-cdk&cdkver=2&sort=downloadsDesc&offset=0) é um recurso para ajudá-lo a descobrir construções adicionais de AWS terceiros e da comunidade CDK de código aberto.

### Escrever seus próprios constructos
<a name="constructs-author"></a>

Além de usar constructos existentes, você também pode escrever seus próprios constructos e permitir que qualquer pessoa os use em suas aplicações. Todas as construções são iguais no AWS CDK. As construções da AWS Construct Library são tratadas da mesma forma que uma construção de uma biblioteca de terceiros publicada viaNPM,Maven, ouPyPI. Os constructos publicados no repositório interno de pacotes da sua empresa também são tratados da mesma forma.

Para declarar um novo constructo, crie uma classe que estenda a classe de base do [Constructo](https://docs.aws.amazon.com/cdk/api/v2/docs/constructs.Construct.html) no pacote `constructs` e siga o padrão dos argumentos do inicializador.

O exemplo a seguir mostra como declarar um constructo que representa um bucket do Amazon S3. O bucket do S3 envia uma notificação do Amazon Simple Notiﬁcation Service (Amazon SNS) toda vez que alguém carrega um arquivo nele.

**Example**  

```
export interface NotifyingBucketProps {
  prefix?: string;
}

export class NotifyingBucket extends Construct {
  constructor(scope: Construct, id: string, props: NotifyingBucketProps = {}) {
    super(scope, id);
    const bucket = new s3.Bucket(this, 'bucket');
    const topic = new sns.Topic(this, 'topic');
    bucket.addObjectCreatedNotification(new s3notify.SnsDestination(topic),
      { prefix: props.prefix });
  }
}
```

```
class NotifyingBucket extends Construct {
  constructor(scope, id, props = {}) {
    super(scope, id);
    const bucket = new s3.Bucket(this, 'bucket');
    const topic = new sns.Topic(this, 'topic');
    bucket.addObjectCreatedNotification(new s3notify.SnsDestination(topic),
      { prefix: props.prefix });
  }
}

module.exports = { NotifyingBucket }
```

```
class NotifyingBucket(Construct):

    def __init__(self, scope: Construct, id: str, *, prefix=None):
        super().__init__(scope, id)
        bucket = s3.Bucket(self, "bucket")
        topic = sns.Topic(self, "topic")
        bucket.add_object_created_notification(s3notify.SnsDestination(topic),
            s3.NotificationKeyFilter(prefix=prefix))
```

```
public class NotifyingBucket extends Construct {

    public NotifyingBucket(final Construct scope, final String id) {
        this(scope, id, null, null);
    }

    public NotifyingBucket(final Construct scope, final String id, final BucketProps props) {
        this(scope, id, props, null);
    }

    public NotifyingBucket(final Construct scope, final String id, final String prefix) {
        this(scope, id, null, prefix);
    }

    public NotifyingBucket(final Construct scope, final String id, final BucketProps props, final String prefix) {
        super(scope, id);

        Bucket bucket = new Bucket(this, "bucket");
        Topic topic = new Topic(this, "topic");
        if (prefix != null)
            bucket.addObjectCreatedNotification(new SnsDestination(topic),
                NotificationKeyFilter.builder().prefix(prefix).build());
     }
}
```

```
public class NotifyingBucketProps : BucketProps
{
    public string Prefix { get; set; }
}

public class NotifyingBucket : Construct
{
    public NotifyingBucket(Construct scope, string id, NotifyingBucketProps props = null) : base(scope, id)
    {
        var bucket = new Bucket(this, "bucket");
        var topic = new Topic(this, "topic");
        bucket.AddObjectCreatedNotification(new SnsDestination(topic), new NotificationKeyFilter
        {
            Prefix = props?.Prefix
        });
    }
}
```

```
type NotifyingBucketProps struct {
	awss3.BucketProps
	Prefix *string
}

func NewNotifyingBucket(scope constructs.Construct, id *string, props *NotifyingBucketProps) awss3.Bucket {
	var bucket awss3.Bucket
	if props == nil {
		bucket = awss3.NewBucket(scope, jsii.String(*id+"Bucket"), nil)
	} else {
		bucket = awss3.NewBucket(scope, jsii.String(*id+"Bucket"), &props.BucketProps)
	}
	topic := awssns.NewTopic(scope, jsii.String(*id+"Topic"), nil)
	if props == nil {
		bucket.AddObjectCreatedNotification(awss3notifications.NewSnsDestination(topic))
	} else {
		bucket.AddObjectCreatedNotification(awss3notifications.NewSnsDestination(topic), &awss3.NotificationKeyFilter{
			Prefix: props.Prefix,
		})
	}
	return bucket
}
```

**nota**  
Nosso constructo `NotifyingBucket` não herda não do `Bucket`, mas sim do `Construct`. Estamos usando composição, não herança, para agrupar um bucket do Amazon S3 e um tópico do Amazon SNS. Em geral, a composição é preferida à herança ao desenvolver construções de AWS CDK.

O construtor `NotifyingBucket` tem uma assinatura de constructo típica: `scope`, `id` e `props`. O último argumento, `props`, é opcional (obtém o valor padrão `{}`) porque todos os props são opcionais. (A classe de base do `Construct` não aceita um argumento `props`.) É possível definir uma instância desse constructo em sua aplicação sem `props`, por exemplo:

**Example**  

```
new NotifyingBucket(this, 'MyNotifyingBucket');
```

```
new NotifyingBucket(this, 'MyNotifyingBucket');
```

```
NotifyingBucket(self, "MyNotifyingBucket")
```

```
new NotifyingBucket(this, "MyNotifyingBucket");
```

```
new NotifyingBucket(this, "MyNotifyingBucket");
```

```
NewNotifyingBucket(stack, jsii.String("MyNotifyingBucket"), nil)
```

Ou você pode usar `props` (em Java, um parâmetro adicional) para especificar o prefixo do caminho a ser filtrado, por exemplo:

**Example**  

```
new NotifyingBucket(this, 'MyNotifyingBucket', { prefix: 'images/' });
```

```
new NotifyingBucket(this, 'MyNotifyingBucket', { prefix: 'images/' });
```

```
NotifyingBucket(self, "MyNotifyingBucket", prefix="images/")
```

```
new NotifyingBucket(this, "MyNotifyingBucket", "/images");
```

```
new NotifyingBucket(this, "MyNotifyingBucket", new NotifyingBucketProps
{
    Prefix = "/images"
});
```

```
NewNotifyingBucket(stack, jsii.String("MyNotifyingBucket"), &NotifyingBucketProps{
	Prefix: jsii.String("images/"),
})
```

Normalmente, você também gostaria de expor algumas propriedades ou métodos em seus constructos. Não é muito útil ter um tópico escondido atrás de seu constructo, porque os usuários de seu constructo não conseguem assiná-lo. Adicionar uma propriedade `topic` permite que os consumidores acessem o tópico interno, conforme mostrado no exemplo a seguir:

**Example**  

```
export class NotifyingBucket extends Construct {
  public readonly topic: sns.Topic;

  constructor(scope: Construct, id: string, props: NotifyingBucketProps) {
    super(scope, id);
    const bucket = new s3.Bucket(this, 'bucket');
    this.topic = new sns.Topic(this, 'topic');
    bucket.addObjectCreatedNotification(new s3notify.SnsDestination(this.topic), { prefix: props.prefix });
  }
}
```

```
class NotifyingBucket extends Construct {

  constructor(scope, id, props) {
    super(scope, id);
    const bucket = new s3.Bucket(this, 'bucket');
    this.topic = new sns.Topic(this, 'topic');
    bucket.addObjectCreatedNotification(new s3notify.SnsDestination(this.topic), { prefix: props.prefix });
  }
}

module.exports = { NotifyingBucket };
```

```
class NotifyingBucket(Construct):

    def __init__(self, scope: Construct, id: str, *, prefix=None, **kwargs):
        super().__init__(scope, id)
        bucket = s3.Bucket(self, "bucket")
        self.topic = sns.Topic(self, "topic")
        bucket.add_object_created_notification(s3notify.SnsDestination(self.topic),
            s3.NotificationKeyFilter(prefix=prefix))
```

```
public class NotifyingBucket extends Construct {

    public Topic topic = null;

    public NotifyingBucket(final Construct scope, final String id) {
        this(scope, id, null, null);
    }

    public NotifyingBucket(final Construct scope, final String id, final BucketProps props) {
        this(scope, id, props, null);
    }

    public NotifyingBucket(final Construct scope, final String id, final String prefix) {
        this(scope, id, null, prefix);
    }

    public NotifyingBucket(final Construct scope, final String id, final BucketProps props, final String prefix) {
        super(scope, id);

        Bucket bucket = new Bucket(this, "bucket");
        topic = new Topic(this, "topic");
        if (prefix != null)
            bucket.addObjectCreatedNotification(new SnsDestination(topic),
                NotificationKeyFilter.builder().prefix(prefix).build());
     }
}
```

```
public class NotifyingBucket : Construct
{
    public readonly Topic topic;

    public NotifyingBucket(Construct scope, string id, NotifyingBucketProps props = null) : base(scope, id)
    {
        var bucket = new Bucket(this, "bucket");
        topic = new Topic(this, "topic");
        bucket.AddObjectCreatedNotification(new SnsDestination(topic), new NotificationKeyFilter
        {
            Prefix = props?.Prefix
        });
    }
}
```
Para fazer isso em Go, precisaremos de um pouco mais de encanamento. Nossa função original `NewNotifyingBucket` retornou um `awss3.Bucket`. Precisaremos estender o `Bucket` para incluir um membro do `topic` criando uma estrutura `NotifyingBucket`. Nossa função então retornará esse tipo.  

```
type NotifyingBucket struct {
	awss3.Bucket
	topic awssns.Topic
}

func NewNotifyingBucket(scope constructs.Construct, id *string, props *NotifyingBucketProps) NotifyingBucket {
	var bucket awss3.Bucket
	if props == nil {
		bucket = awss3.NewBucket(scope, jsii.String(*id+"Bucket"), nil)
	} else {
		bucket = awss3.NewBucket(scope, jsii.String(*id+"Bucket"), &props.BucketProps)
	}
	topic := awssns.NewTopic(scope, jsii.String(*id+"Topic"), nil)
	if props == nil {
		bucket.AddObjectCreatedNotification(awss3notifications.NewSnsDestination(topic))
	} else {
		bucket.AddObjectCreatedNotification(awss3notifications.NewSnsDestination(topic), &awss3.NotificationKeyFilter{
			Prefix: props.Prefix,
		})
	}
	var nbucket NotifyingBucket
	nbucket.Bucket = bucket
	nbucket.topic = topic
	return nbucket
}
```

Agora, os consumidores podem assinar o tópico, por exemplo:

**Example**  

```
const queue = new sqs.Queue(this, 'NewImagesQueue');
const images = new NotifyingBucket(this, '/images');
images.topic.addSubscription(new sns_sub.SqsSubscription(queue));
```

```
const queue = new sqs.Queue(this, 'NewImagesQueue');
const images = new NotifyingBucket(this, '/images');
images.topic.addSubscription(new sns_sub.SqsSubscription(queue));
```

```
queue = sqs.Queue(self, "NewImagesQueue")
images = NotifyingBucket(self, prefix="Images")
images.topic.add_subscription(sns_sub.SqsSubscription(queue))
```

```
NotifyingBucket images = new NotifyingBucket(this, "MyNotifyingBucket", "/images");
images.topic.addSubscription(new SqsSubscription(queue));
```

```
var queue = new Queue(this, "NewImagesQueue");
var images = new NotifyingBucket(this, "MyNotifyingBucket", new NotifyingBucketProps
{
    Prefix = "/images"
});
images.topic.AddSubscription(new SqsSubscription(queue));
```

```
	queue := awssqs.NewQueue(stack, jsii.String("NewImagesQueue"), nil)
	images := NewNotifyingBucket(stack, jsii.String("MyNotifyingBucket"), &NotifyingBucketProps{
		Prefix: jsii.String("/images"),
	})
	images.topic.AddSubscription(awssnssubscriptions.NewSqsSubscription(queue, nil))
```

## Saiba mais
<a name="constructs-learn"></a>

O vídeo a seguir fornece uma visão geral abrangente dos constructos do CDK e explica como você pode usá-los em suas aplicações do CDK.

[![AWS Videos](http://img.youtube.com/vi/https://www.youtube.com/embed/PzU-i0rJPGw?rel=0/0.jpg)](http://www.youtube.com/watch?v=https://www.youtube.com/embed/PzU-i0rJPGw?rel=0)
