

這是 AWS CDK v2 開發人員指南。較舊的 CDK v1 已於 2022 年 6 月 1 日進入維護，並於 2023 年 6 月 1 日結束支援。

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 設定 CDK Toolkit 訊息和互動
<a name="toolkit-library-configure-messages"></a>

 AWS CDK Toolkit Library 提供 ` [IIoHost](https://docs.aws.amazon.com/cdk/api/toolkit-lib/Package/toolkit-lib/Interface/IIoHost/) `界面，可自訂在 CDK 操作期間如何處理訊息和互動，讓您控制部署進度、錯誤訊息和使用者提示的顯示，以更好地整合應用程式的使用者體驗。

在執行部署或合成等操作之前，您需要了解 CDK Toolkit 如何與使用者通訊。`IIoHost` 界面可做為 CDK Toolkit 與應用程式之間的通訊管道，同時處理傳出訊息和傳入使用者回應。

當 CDK Toolkit 執行操作時，它會透過兩個主要機制進行通訊：
+  **訊息**：通知您操作進度的資訊輸出 （例如「開始部署」或「已建立資源」)。
+  **請求**：需要輸入或確認的決策點 （例如「您要部署這些變更嗎？」)，讓您有機會提供事先不需要的資訊。

## 使用 `IIoHost` 界面
<a name="toolkit-library-configure-messages-iiohost"></a>

`IIoHost` 介面包含兩種主要方法：

1.  `notify`：處理單向資訊性訊息。

1.  `requestResponse`：處理需要回應的互動式請求。

```
import { IoMessage, IoRequest } from '@aws-cdk/toolkit-lib';

interface IIoHost {
  // Handle informational messages
  notify(message: IoMessage): Promise<void>;

  // Handle requests that need responses
  requestResponse(request: IoRequest): Promise<any>;
}
```

## 訊息層級和請求類型
<a name="toolkit-library-configure-messages-levels"></a>

CDK Toolkit 會產生多種類型的訊息和請求：

### 訊息層級
<a name="_message_levels"></a>
+  **偵錯**：疑難排解的詳細訊息。
+  **錯誤**：可能影響 操作的錯誤訊息。
+  **資訊**：一般資訊訊息。
+  **結果** - 操作的主要訊息。
+  **追蹤**：非常詳細的執行流程資訊。
+  **警告**：不會阻止操作的警告訊息。

如需完整清單，請參閱 * AWS CDK Toolkit Library API 參考*中的 [IoMessages 登錄](https://docs.aws.amazon.com/cdk/api/toolkit-lib/message-registry/)檔。

### 請求類型
<a name="_request_types"></a>

CDK Toolkit 會在需要使用者輸入或確認時傳送請求。這些是允許回應的特殊訊息。如果未提供任何回應， Toolkit 將在可用時使用預設回應。

## 基本`IIoHost`實作
<a name="toolkit-library-configure-messages-basic"></a>

以下是實作自訂 io 主機的簡單範例：

```
import { Toolkit } from '@aws-cdk/toolkit-lib';

// Create a toolkit with custom message handling
const toolkit = new Toolkit({
  ioHost: {
    // Implementing the IIoHost interface
    // Handle informational messages
    notify: async function (msg) {
      // Example: Handle different message levels appropriately
      switch (msg.level) {
        case 'error':
          console.error(`[${msg.time}] ERROR: ${msg.message}`);
          break;
        case 'warning':
          console.warn(`[${msg.time}] WARNING: ${msg.message}`);
          break;
        case 'info':
          console.info(`[${msg.time}] INFO: ${msg.message}`);
          break;
        case 'debug':
          console.debug(`[${msg.time}] DEBUG: ${msg.message}`);
          break;
        case 'trace':
          console.debug(`[${msg.time}] TRACE: ${msg.message}`);
          break;
        default:
          console.log(`[${msg.time}] ${msg.level}: ${msg.message}`);
      }
    },

    // Handle requests that need responses
    requestResponse: async function (msg) {
      // Example: Log the request and use default response
      console.log(`Request: ${msg.message}, using default: ${msg.defaultResponse}`);
      return msg.defaultResponse;

      // Or implement custom logic to provide responses
      // if (msg.type === 'deploy') {
      //   return promptUserForDeployment(msg);
      // }
    }
  } as IIoHost // Explicitly cast to IIoHost interface
});
```

CDK Toolkit 會等待每次呼叫完成，讓您可以在處理訊息時執行非同步操作，例如 HTTP 請求或使用者提示。

## 預設`IIoHost`行為
<a name="toolkit-library-configure-messages-iiohost-default"></a>

如果您未提供自訂 io 主機，CDK Toolkit Library 會使用預設的非互動式實作：
+ 訊息的主控台輸出 （針對不同的訊息類型使用適當的顏色）。
+ 完全非互動式，不會提示使用者輸入。
+ 盡可能自動使用預設回應 （相當於對提示回答「是」)。
+ 需要輸入但沒有預設回應時失敗。

此預設行為適用於無人值守的操作，但不適用於互動式命令列應用程式。對於需要使用者互動的命令列應用程式，您需要實作自訂 io 主機。自訂實作也適用於與記錄系統、UIs 或其他特殊環境整合。

## 進階 io 主機實作
<a name="toolkit-library-configure-messages-advanced"></a>

對於更複雜的案例，我們建議將 `NonInteractiveIoHost`類別擴展為起點。此方法可讓您利用現有的非互動式實作，同時只自訂您需要變更的特定行為。

以下是擴展基本實作的自訂 io 主機範例：

```
import { NonInteractiveIoHost } from '@aws-cdk/toolkit-lib';

class MyCustomIoHost extends NonInteractiveIoHost {
  // Override only the methods you need to customize

  // Example: Custom implementation for notify
  public async notify(msg: IoMessage<unknown>): Promise<void> {
    // Add custom notification handling logic
    if (msg.level === 'error') {
      console.error(`ERROR: ${msg.message}`);
      // Optionally log to a service or notify a monitoring system
      await this.logToMonitoringService(msg);
    } else {
      await super.notify(msg);
    }
  }

  // Example: Custom implementation for requestResponse
  public async requestResponse<T, U>(request: IoRequest<T, U>): Promise<U> {
    // Implement custom request handling
    console.log(`Received request: ${request.message}`);
    return request.defaultResponse;
  }

  private async logToMonitoringService(msg: IoMessage<unknown>): Promise<void> {
    // Implementation for monitoring service integration
    console.log(`Logging to monitoring service: ${msg.level} - ${msg.message}`);
  }
}
```

這種方法比從頭開始實作整個`IIoHost`界面更可維護，因為您只需要覆寫需要自訂行為的特定方法。

## 與不同環境整合
<a name="toolkit-library-configure-messages-integration"></a>

### Web 應用程式整合
<a name="_web_application_integration"></a>

```
import { Toolkit } from '@aws-cdk/toolkit-lib';

// Example for integrating with a web application
const toolkit = new Toolkit({
  ioHost: {
    notify: async function (msg) {
      // Send message to frontend via WebSocket
      webSocketServer.send(JSON.stringify({
        type: 'cdk-notification',
        messageLevel: msg.level,
        message: msg.message,
        time: msg.time
      }));
    },

    requestResponse: async function (msg) {
      // Create a promise that will be resolved when the user responds
      return new Promise((resolve) => {
        const requestId = generateUniqueId();

        // Store the resolver function
        pendingRequests[requestId] = resolve;

        // Send request to frontend
        webSocketServer.send(JSON.stringify({
          type: 'cdk-request',
          requestId: requestId,
          requestType: msg.type,
          message: msg.message,
          defaultResponse: msg.defaultResponse
        }));

        // Frontend would call an API endpoint with the response,
        // which would then call pendingRequests[requestId](response)
      });
    }
  } as IIoHost // Explicitly cast to IIoHost interface
});
```

### CI/CD 環境整合
<a name="_cicd_environment_integration"></a>

```
import { Toolkit } from '@aws-cdk/toolkit-lib';

// Example for CI/CD environments (non-interactive)
const toolkit = new Toolkit({
  ioHost: {
    notify: async function (msg) {
      // Log all messages with appropriate level
      switch (msg.level) {
        case 'error':
          console.error(msg.message);
          break;
        case 'warning':
          console.warn(msg.message);
          break;
        default:
          console.log(msg.message);
      }
    },

    requestResponse: async function (msg) {
      // In CI/CD, always use default responses or predefined answers
      console.log(`Auto-responding to request: ${msg.message} with ${msg.defaultResponse}`);
      return msg.defaultResponse;
    }
  } as IIoHost // Explicitly cast to IIoHost interface
});
```

## io 主機實作的最佳實務
<a name="toolkit-library-configure-messages-best-practices"></a>

實作自訂 io 主機時，請考慮下列最佳實務：
+  **錯誤處理**：在 io 主機方法中實作強大的錯誤處理，以防止失敗影響 CDK 操作。
+  **逾時**：考慮實作使用者互動的逾時，以防止無限期等待。
+  **記錄**：將重要訊息儲存在日誌中以進行疑難排解，尤其是在非互動環境中。
+  **預設回應**：為無法與使用者互動的自動化環境提供合理的預設回應。
+  **進度指示**：對於長時間執行的操作，提供明確的進度指標來改善使用者體驗。

下列範例透過實作具有錯誤處理、使用者互動逾時和適當記錄的自訂 io 主機，來示範這些最佳實務。此實作適用於您需要平衡使用者回應能力與可靠操作的互動式應用程式：

```
import { Toolkit } from '@aws-cdk/toolkit-lib';

// Example with error handling and timeouts
const toolkit = new Toolkit({
  ioHost: {
    notify: async function (msg) {
      try {
        console.log(`[${msg.time}] ${msg.level}: ${msg.message}`);
        // Additional logging or UI updates
      } catch (error) {
        // Ensure errors in notification handling don't break the CDK operation
        console.error("Error handling notification:", error);
      }
    },

    requestResponse: async function (msg) {
      try {
        // Implement timeout for user response
        const response = await Promise.race([
          getUserResponse(msg),
          new Promise(resolve => setTimeout(() => resolve(msg.defaultResponse), 60000))
        ]);
        return response;
      } catch (error) {
        console.error("Error handling request:", error);
        return msg.defaultResponse;
      }
    }
  } as IIoHost // Explicitly cast to IIoHost interface
});
```

## 故障診斷
<a name="toolkit-library-configure-messages-troubleshooting"></a>

實作自訂 io 主機時的考量事項：
+  **未處理的 promise 拒絕**：確保所有非同步操作都使用 try/catch 區塊正確處理。
+  **無限等待**：為所有使用者互動實作逾時，以防止應用程式掛起。
+  **缺少訊息層級**：準備好處理未來 CDK 版本中可能新增的新訊息層級。
+  **不一致的回應**：確保您的 requestResponse 實作以預期的格式傳回值。

下列範例示範處理訊息層級的強大方法，包括正常處理未來 CDK 版本中可能引進的未知訊息類型。此實作可確保您的 io 主機與 CDK 更新相容，同時維護適當的記錄：

```
import { Toolkit } from '@aws-cdk/toolkit-lib';

// Example of handling unknown message levels
const toolkit = new Toolkit({
  ioHost: {
    notify: async function (msg) {
      // Handle known levels
      const knownLevels = ['info', 'warning', 'error', 'debug', 'trace', 'status'];

      if (knownLevels.includes(msg.level)) {
        // Handle known level
        handleKnownMessageLevel(msg);
      } else {
        // Handle unknown level as info
        console.log(`Unknown message level "${msg.level}": ${msg.message}`);
      }
    },

    requestResponse: async function (msg) {
      // Default implementation
      return msg.defaultResponse;
    }
  } as IIoHost // Explicitly cast to IIoHost interface
});
```