

这是 AWS CDK v2 开发者指南。旧版 CDK v1 于 2022 年 6 月 1 日进入维护阶段，并于 2023 年 6 月 1 日终止支持。

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 使用 AWS CDK 库
<a name="work-with"></a>

导入并使用 AWS 云开发工具包 (AWS CDK) 库，以使用[支持的编程语言](languages.md)来定义您的 AWS 云基础设施。

## 导入 AWS CDK 库
<a name="work-with-library"></a>

通常通过 [AWS CDK 库](libraries.md) 的 TypeScript 包名称 `aws-cdk-lib` 来引用该库。实际的包名称因语言而异。以下是如何安装和导入 CDK 库的示例：

**Example**  


|  |  | 
| --- |--- |
|   **安装**   |   `npm install aws-cdk-lib`   | 
|   **导入**：  |   `import * as cdk from 'aws-cdk-lib';`   | 


|  |  | 
| --- |--- |
|   **安装**   |   `npm install aws-cdk-lib`   | 
|   **导入**：  |   `const cdk = require('aws-cdk-lib');`   | 


|  |  | 
| --- |--- |
|   **安装**   |   `python -m pip install aws-cdk-lib`   | 
|   **导入**：  |   `import aws_cdk as cdk`   | 


|  |  | 
| --- |--- |
|   **在 `pom.xml` 中，添加**   |   `Group software.amazon.awscdk; artifact aws-cdk-lib`   | 
|   **导入**：  |   `import software.amazon.awscdk.App;`   | 


|  |  | 
| --- |--- |
|   **安装**   |   `dotnet add package Amazon.CDK.Lib`   | 
|   **导入**：  |   `using Amazon.CDK;`   | 


|  |  | 
| --- |--- |
|   **安装**   |   `go get github.com/aws/aws-cdk-go/awscdk/v2`   | 
|   **导入**：  |  <pre>import (<br />  "github.com/aws/aws-cdk-go/awscdk/v2"<br />)</pre>  | 

`construct` 基类和支持代码位于 `constructs` 库中。实验性构造（其中 API 仍在完善中）作为单独的模块进行分发。

## 使用 AWS CDK API 参考
<a name="work-with-library-reference"></a>

采用 AWS CDK 进行开发时，请使用 [AWS CDK API 参考](libraries.md#libraries-reference)。

每个模块的参考资料分为以下几个部分。
+  *概述*：使用 AWS CDK 中的服务需要了解的介绍性材料，包括概念和示例。
+  *构造*：表示一个或多个具体 AWS 资源的库类。这些是“精选”（L2）资源或模式（L3 资源），可提供具有合理默认值的高级别接口。
+  *类*：非构造类，可提供模块中构造所使用的功能。
+  *结构*：数据结构（属性捆绑包），可定义复合值结构，例如属性（构造的 `props` 参数）和选项。
+  *接口*：所有名称以“I”为开头的接口，可定义相应构造或其他类的绝对最低功能。CDK 使用构造接口来表示在您的 AWS CDK 应用程序之外定义并由 `Bucket.fromBucketArn()` 等方法引用的 AWS 资源。
+  *枚举*：用于指定某些构造参数的命名值的集合。使用枚举值可允许 CDK 在合成过程中检查这些值的有效性。
+  *CloudFormation 资源*：名称以“Cfn”开头的这些 L1 构造，正好代表了 CloudFormation 规范中定义的资源。这些资源随每个 CDK 版本根据该规范自动生成。每个 L2 或 L3 构造都封装了一个或多个 CloudFormation 资源。
+  *CloudFormation 属性类型*：定义每个 CloudFormation 资源属性的命名值的集合。

## 接口与构造类的比较
<a name="work-with-library-interfaces"></a>

AWS CDK 以特定的方式使用接口，即使您熟悉作为编程概念的接口，这种方式也可能并不明显。

AWS CDK 支持通过 `Bucket.fromBucketArn()` 等方法来使用 CDK 应用程序之外定义的资源。无法对外部资源进行修改，并且可能不具有使用 `Bucket` 类等工具在您的 CDK 应用程序中定义的资源提供的所有功能。因此，接口代表了 CDK 中针对给定 AWS 资源类型（*包括外部资源*）可用的最低功能。

所以在 CDK 应用程序中实例化资源时，应始终使用具体的类，例如 `Bucket`。在您自己的构造之一中指定要接受的参数类型时，如果您已准备好处理外部资源（即无需对其进行更改），请使用 `IBucket` 等接口类型。如果需要 CDK 定义的构造，请指定可以使用的最通用的类型。

有些接口是与特定类（而不是构造）相关的属性或选项捆绑包的最低版本。当进行子类化以接受要传递给父类的参数时，此类接口会很有用。如果您需要一个或多个其他属性，则需要从该接口或更具体的类型来实现或派生。

**注意**  
AWS CDK 支持的某些编程语言不具备接口功能。在这些语言中，接口只是普通的类。您可以通过其名称来进行识别，这些名称遵循首字母为“I”后跟其他构造名称的模式（例如 `IBucket`）。适用于相同的规则。

## 管理依赖项
<a name="work-with-cdk-dependencies"></a>

使用包管理工具来管理 AWS CDK 应用程序或库的依赖项。这些工具通常与编程语言一起使用。

通常，AWS CDK 支持该语言的标准或官方包管理工具（如有）。否则，AWS CDK 将支持该语言中最常用或最广泛支持的管理工具。您也可以使用其他工具，特别是如果与支持的工具配合使用。但是，官方对其他工具的支持有限。

AWS CDK 支持以下包管理器：


| 语言 | 支持的包管理工具 | 
| --- | --- | 
|  TypeScript/JavaScript  |  NPM（节点包管理器）或 Yarn  | 
|  Python  |  PIP（Python 的包安装程序）  | 
|  Java  |  Maven  | 
|  C\$1  |  NuGet  | 
|  Go（转到）  |  Go 模块  | 

使用 AWS CDK CLI `cdk init` 命令创建新项目时，会自动指定 CDK 核心库和稳定构造的依赖项。

有关管理受支持编程语言依赖项的更多信息，请参阅以下内容：
+  [在 TypeScript 中管理依赖项](work-with-cdk-typescript.md#work-with-cdk-typescript-dependencies)。
+  [在 JavaScript 中管理依赖项](work-with-cdk-javascript.md#work-with-cdk-javascript-dependencies)。
+  [在 Python 中管理依赖项](work-with-cdk-python.md#work-with-cdk-python-dependencies)。
+  [在 Java 中管理依赖项](work-with-cdk-java.md#work-with-cdk-java-dependencies)。
+  [在 C\$1 中管理依赖项](work-with-cdk-csharp.md#work-with-cdk-csharp-dependencies)。
+  [在 Go 中管理依赖项](work-with-cdk-go.md#work-with-cdk-go-dependencies)。

## 将 TypeScript 中的 AWS CDK 与其他语言进行比较
<a name="work-with-cdk-compare"></a>

TypeScript 是支持开发 AWS CDK 应用程序所支持的第一种语言。因此，大量示例 CDK 代码都使用 TypeScript 进行编写。如果您正在使用另一种语言进行开发，那么请将 AWS CDK 代码在 TypeScript 中的实现方式与您选择语言中的实现方式进行比较，这可能会很有用。这有助于您在整个文档中使用示例。

## 导入模块
<a name="work-with-cdk-compare-import"></a>

**Example**  
TypeScript 支持导入整个命名空间，也支持从某个命名空间中导入单个对象。每个命名空间都包含用于给定 AWS 服务的构造和其他类。  

```
// Import main CDK library as cdk
import * as cdk from 'aws-cdk-lib';   // ES6 import preferred in TS
const cdk = require('aws-cdk-lib');   // Node.js require() preferred in JS

// Import specific core CDK classes
import { Stack, App } from 'aws-cdk-lib';
const { Stack, App } = require('aws-cdk-lib');

// Import AWS S3 namespace as s3 into current namespace
import { aws_s3 as s3 } from 'aws-cdk-lib';   // TypeScript
const s3 = require('aws-cdk-lib/aws-s3');     // JavaScript

// Having imported cdk already as above, this is also valid
const s3 = cdk.aws_s3;

// Now use s3 to access the S3 types
const bucket = s3.Bucket(...);

// Selective import of s3.Bucket
import { Bucket } from 'aws-cdk-lib/aws-s3';        // TypeScript
const { Bucket } = require('aws-cdk-lib/aws-s3');   // JavaScript

// Now use Bucket to instantiate an S3 bucket
const bucket = Bucket(...);
```
与 TypeScript 一样，Python 也支持具有命名空间的模块导入和选择性导入。Python 中的命名空间类似于 **aws\$1cdk.** *xxx*，其中 *xxx* 表示 AWS 服务名称，例如 **s3** 代表 Amazon S3。（这些示例中使用了 Amazon S3。）  

```
# Import main CDK library as cdk
import aws_cdk as cdk

# Selective import of specific core classes
from aws_cdk import Stack, App

# Import entire module as s3 into current namespace
import aws_cdk.aws_s3 as s3

# s3 can now be used to access classes it contains
bucket = s3.Bucket(...)

# Selective import of s3.Bucket into current namespace
from aws_cdk.s3 import Bucket

# Bucket can now be used to instantiate a bucket
bucket = Bucket(...)
```
Java 的导入方式与 TypeScript 有所不同。每个 import 语句要么从给定包中导入单个类名，要么导入该包中定义的所有类（使用 `\*`）。可以使用类本身的类名（如果已导入该类），也可以使用包含其包的*限定*类名来访问类。  
库的命名类似于 AWS 构造库的 `software.amazon.awscdk.services.xxx`（其中 `software.amazon.awscdk` 为主库）。AWS CDK 软件包的 Maven 组 ID 为 `software.amazon.awscdk`。  

```
// Make certain core classes available
import software.amazon.awscdk.Stack;
import software.amazon.awscdk.App;

// Make all Amazon S3 construct library classes available
import software.amazon.awscdk.services.s3.*;

// Make only Bucket and EventType classes available
import software.amazon.awscdk.services.s3.Bucket;
import software.amazon.awscdk.services.s3.EventType;

// An imported class may now be accessed using the simple class name (assuming that name
// does not conflict with another class)
Bucket bucket = Bucket.Builder.create(...).build();

// We can always use the qualified name of a class (including its package) even without an
// import directive
software.amazon.awscdk.services.s3.Bucket bucket =
    software.amazon.awscdk.services.s3.Bucket.Builder.create(...)
        .build();

// Java 10 or later can use var keyword to avoid typing the type twice
var bucket =
    software.amazon.awscdk.services.s3.Bucket.Builder.create(...)
        .build();
```
在 C\$1 中，您可以使用 `using` 指令导入类型。有两种方式可供选择。一种是使用纯名称来访问指定命名空间中的所有类型。另一种则是可以使用别名来引用命名空间本身。  
软件包的命名类似于 AWS 构造库软件包的 `Amazon.CDK.AWS.xxx`。（其中 `Amazon.CDK` 为核心模块。）  

```
// Make CDK base classes available under cdk
using cdk = Amazon.CDK;

// Make all Amazon S3 construct library classes available
using Amazon.CDK.AWS.S3;

// Now we can access any S3 type using its name
var bucket = new Bucket(...);

// Import the S3 namespace under an alias
using s3 = Amazon.CDK.AWS.S3;

// Now we can access an S3 type through the namespace alias
var bucket = new s3.Bucket(...);

// We can always use the qualified name of a type (including its namespace) even without a
// using directive
var bucket = new Amazon.CDK.AWS.S3.Bucket(...);
```
每个 AWS 构造库模块都作为 Go 包提供。  

```
import (
    "github.com/aws/aws-cdk-go/awscdk/v2"           // CDK core package
    "github.com/aws/aws-cdk-go/awscdk/v2/awss3"     // AWS S3 construct library module
)

// now instantiate a bucket
bucket := awss3.NewBucket(...)

// use aliases for brevity/clarity
import (
    cdk "github.com/aws/aws-cdk-go/awscdk/v2"           // CDK core package
    s3  "github.com/aws/aws-cdk-go/awscdk/v2/awss3"     // AWS S3 construct library module
)

bucket := s3.NewBucket(...)
```

## 实例化构造
<a name="work-with-cdk-compare-class"></a>

 AWS CDK 构造类在所有支持的语言中都具有相同的名称。大多数语言都使用 `new` 关键字来实例化类（Python 和 Go 则不使用）。此外，在大多数语言中，关键字`this` 是指当前实例。（按照惯例，Python 使用 `self`。） 您应该将对当前实例的引用作为 `scope` 参数传递给您创建的每个构造。

AWS CDK 构造的第三个参数是 `props`，这是一个包含构建构造所需属性的对象。此参数可能是可选的，但是当需要时，支持的语言会以惯用方式进行处理。属性的名称也符合该语言的标准命名模式。

**Example**  

```
// Instantiate default Bucket
const bucket = new s3.Bucket(this, 'amzn-s3-demo-bucket');

// Instantiate Bucket with bucketName and versioned properties
const bucket = new s3.Bucket(this, 'amzn-s3-demo-bucket', {
  bucketName: 'amzn-s3-demo-bucket',
   versioned: true,
});

// Instantiate Bucket with websiteRedirect, which has its own sub-properties
const bucket = new s3.Bucket(this, 'amzn-s3-demo-bucket', {
  websiteRedirect: {host: 'aws.amazon.com'}});
```
Python 在实例化类时不使用 `new` 关键字。使用关键字参数来表示属性参数，这些关键字参数使用 `snake_case` 来命名。  
如果 props 值本身就是属性捆绑包，则由以该属性命名的类表示，该类接受子属性的关键字参数。  
在 Python 中，当前实例作为第一个参数传递给方法，按照惯例命名为 `self`。  

```
# Instantiate default Bucket
bucket = s3.Bucket(self, "amzn-s3-demo-bucket")

# Instantiate Bucket with bucket_name and versioned properties
bucket = s3.Bucket(self, "amzn-s3-demo-bucket", bucket_name="amzn-s3-demo-bucket", versioned=true)

# Instantiate Bucket with website_redirect, which has its own sub-properties
bucket = s3.Bucket(self, "amzn-s3-demo-bucket", website_redirect=s3.WebsiteRedirect(
            host_name="aws.amazon.com"))
```
在 Java 中，props 参数由一个名为 `XxxxProps` 的类表示（例如，`BucketProps` 表示 `Bucket` 构造的 props）。您可以使用生成器模式来构建 props 参数。  
每个 `XxxxProps` 类都有一个生成器。每个构造都还具有一个便捷生成器，可以一步构建 props 和构造，如以下示例所示。  
Props 与 TypeScript 中相同，均使用 `camelCase`。  

```
// Instantiate default Bucket
Bucket bucket = Bucket(self, "amzn-s3-demo-bucket");

// Instantiate Bucket with bucketName and versioned properties
Bucket bucket = Bucket.Builder.create(self, "amzn-s3-demo-bucket")
                      .bucketName("amzn-s3-demo-bucket").versioned(true)
                      .build();

# Instantiate Bucket with websiteRedirect, which has its own sub-properties
Bucket bucket = Bucket.Builder.create(self, "amzn-s3-demo-bucket")
                      .websiteRedirect(new websiteRedirect.Builder()
                          .hostName("aws.amazon.com").build())
                      .build();
```
在 C\$1 中，使用对象初始化程序将 props 指定给名为 `XxxxProps` 的类（例如，`BucketProps` 表示 `Bucket` 构造的 props）。  
Props 命名与 TypeScript 类似，唯一的不同是使用 `PascalCase`。  
在实例化构造时使用 `var` 关键字很方便，因此无需键入类名两次。但是，您的本地代码风格指南可能会有所不同。  

```
// Instantiate default Bucket
var bucket = Bucket(self, "amzn-s3-demo-bucket");

// Instantiate Bucket with BucketName and Versioned properties
var bucket =  Bucket(self, "amzn-s3-demo-bucket", new BucketProps {
                      BucketName = "amzn-s3-demo-bucket",
                      Versioned  = true});

// Instantiate Bucket with WebsiteRedirect, which has its own sub-properties
var bucket = Bucket(self, "amzn-s3-demo-bucket", new BucketProps {
                      WebsiteRedirect = new WebsiteRedirect {
                              HostName = "aws.amazon.com"
                      }});
```
要在 Go 中创建构造，请调用函数 `NewXxxxxx`，其中 `Xxxxxxx` 为构造的名称。构造的属性被定义为结构。  
在 Go 中，所有构造参数都是指针，包括数字、布尔值和字符串等值。使用 `jsii.String` 等便捷函数来创建这些指针。  

```
	// Instantiate default Bucket
	bucket := awss3.NewBucket(stack, jsii.String("amzn-s3-demo-bucket"), nil)

	// Instantiate Bucket with BucketName and Versioned properties
	bucket1 := awss3.NewBucket(stack, jsii.String("amzn-s3-demo-bucket"), &awss3.BucketProps{
		BucketName: jsii.String("amzn-s3-demo-bucket"),
		Versioned:  jsii.Bool(true),
	})

	// Instantiate Bucket with WebsiteRedirect, which has its own sub-properties
	bucket2 := awss3.NewBucket(stack, jsii.String("amzn-s3-demo-bucket"), &awss3.BucketProps{
		WebsiteRedirect: &awss3.RedirectTarget{
			HostName: jsii.String("aws.amazon.com"),
		}})
```

## 访问成员
<a name="work-with-cdk-compare-members"></a>

通常会引用构造和其他 AWS CDK 类的特性或属性，并将这些值用作构建其他构造的输入等。前面所述方法的命名差异也适用于此处。此外，无法在 Java 中直接访问成员。相反，会提供一个 getter 方法。

**Example**  
名称为 `camelCase`。  

```
bucket.bucketArn
```
名称为 `snake_case`。  

```
bucket.bucket_arn
```
为每个属性提供了一个 getter 方法；这些名称为 `camelCase`。  

```
bucket.getBucketArn()
```
名称为 `PascalCase`。  

```
bucket.BucketArn
```
名称为 `PascalCase`。  

```
bucket.BucketArn
```

## 枚举常量
<a name="work-with-cdk-compare-enums"></a>

枚举常量的作用域仅限于某个类，并且在所有语言中都具有带下划线的大写名称（有时称为 `SCREAMING_SNAKE_CASE`）。由于类名在除 Go 之外的所有支持的语言中也使用相同的大小写，所以这些语言中的限定枚举名称也相同。

```
s3.BucketEncryption.KMS_MANAGED
```

在 Go 中，枚举常量是指模块命名空间的属性，编写方式如下。

```
awss3.BucketEncryption_KMS_MANAGED
```

## 对象接口
<a name="work-with-cdk-compare-object"></a>

AWS CDK 使用 TypeScript 对象接口来表示某个类实现了一组预期的方法和属性。您可以识别对象接口，因为其名称以 `I` 开头。具体类使用 `implements` 关键字来指示其实现的接口。

**Example**  
JavaScript 不具备接口功能。您可以忽略 `implements` 关键字及其后的类名。

```
import { IAspect, IConstruct } from 'aws-cdk-lib';

class MyAspect implements IAspect {
  public visit(node: IConstruct) {
    console.log('Visited', node.node.path);
  }
}
```
Python 不具备接口功能。但是，对于 AWS CDK 来说，您可以通过 `@jsii.implements(interface)` 来装饰您的类，以此指示接口实现。  

```
from aws_cdk import IAspect, IConstruct
import jsii

@jsii.implements(IAspect)
class MyAspect():
  def visit(self, node: IConstruct) -> None:
    print("Visited", node.node.path)
```

```
import software.amazon.awscdk.IAspect;
import software.amazon.awscdk.IConstruct;

public class MyAspect implements IAspect {
    public void visit(IConstruct node) {
        System.out.format("Visited %s", node.getNode().getPath());
    }
}
```

```
using Amazon.CDK;

public class MyAspect : IAspect
{
    public void Visit(IConstruct node)
    {
        System.Console.WriteLine($"Visited ${node.Node.Path}");
    }
}
```
Go 结构无需明确声明其实现的接口。Go 编译器根据结构上可用的方法和属性来确定实现。例如，在以下代码中，`MyAspect` 实现 `IAspect` 接口，因为其提供了一种采用构造的 `Visit` 方法。  

```
type MyAspect struct {
}

func (a MyAspect) Visit(node constructs.IConstruct) {
	fmt.Println("Visited", *node.Node().Path())
}
```