Configuración de mensajes e interacciones del kit de herramientas de CDK - AWS Cloud Development Kit (AWS CDK) v2

Esta es la segunda versión de la Guía para desarrolladores de AWS CDK. 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.

Configuración de mensajes e interacciones del kit de herramientas de CDK

La biblioteca del kit de herramientas de AWS CDK proporciona la interfaz IIoHost para personalizar la forma en que se gestionan los mensajes y las interacciones durante las operaciones del CDK, lo que le permite controlar la visualización del progreso de la implementación, los mensajes de error y las indicaciones de los usuarios para integrarlos mejor con la experiencia de usuario de la aplicación.

Antes de realizar operaciones como la implementación o la síntesis, debe comprender cómo se comunica el kit de herramientas de CDK con los usuarios. La interfaz IIoHost sirve como canal de comunicación entre el kit de herramientas del CDK y su aplicación, y gestiona tanto los mensajes salientes como las respuestas entrantes de los usuarios.

Cuando el kit de herramientas de CDK ejecuta operaciones, se comunica a través de dos mecanismos principales:

  • Mensajes: resultados informativos que le notifican el progreso de la operación (como “Inicio de la implementación” o “Recurso creado”).

  • Solicitudes: puntos de decisión que requieren información o confirmación (como “¿Desea implementar estos cambios?”) , lo que le da la oportunidad de proporcionar información que de antemano no se sabía que era necesaria.

Uso de la interfaz IIoHost

La interfaz IIoHost consta de dos métodos principales:

  1. notify: gestiona los mensajes informativos unidireccionales.

  2. requestResponse: gestiona las solicitudes interactivas que requieren una respuesta.

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>; }

Niveles de mensajes y tipos de solicitudes

El kit de herramientas de CDK genera varios tipos de mensajes y solicitudes:

Niveles de mensajes

  • Depuración: mensajes detallados para solucionar problemas.

  • Error: mensajes de error que pueden afectar al funcionamiento.

  • Información: mensajes de información general.

  • Resultado: mensaje principal de una operación.

  • Rastreo: información muy detallada del flujo de ejecución.

  • Advertencia: mensajes de advertencia que no impiden el funcionamiento.

Para obtener una lista completa, consulte el registro de IoMessages en la referencia de la API de la biblioteca del kit de herramientas de AWS CDK.

Tipos de solicitud

El kit de herramientas de CDK envía solicitudes cuando necesita información o confirmación por parte del usuario. Se trata de mensajes especiales que dan lugar a una respuesta. Si no se proporciona ninguna respuesta, el kit de herramientas utilizará una respuesta predeterminada cuando esté disponible.

Implementación básica de IIoHost

Este es un ejemplo sencillo de implementación de un host E/S personalizado:

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 });

El kit de herramientas de CDK espera a que se complete cada llamada, lo que le permite realizar operaciones asíncronas, como solicitudes HTTP o mensajes de usuario, al gestionar los mensajes.

Comportamiento IIoHost predeterminado

Si no proporciona un host E/S personalizado, la biblioteca del kit de herramientas de CDK utiliza una implementación no interactiva predeterminada:

  • Resultado de la consola para los mensajes (con los colores adecuados para los diferentes tipos de mensajes).

  • No interactivo en su totalidad y sin solicitudes de entrada al usuario.

  • Utiliza automáticamente las respuestas predeterminadas siempre que es posible (equivalente a responder “sí” a las preguntas).

  • Falla cuando es necesario introducir datos, pero no hay ninguna respuesta predeterminada disponible.

Este comportamiento predeterminado es adecuado para operaciones desatendidas, pero no para aplicaciones interactivas de la línea de comandos. Para las aplicaciones de línea de comandos que requieren la interacción del usuario, necesitará implementar un host E/S personalizado. Las implementaciones personalizadas también son útiles para la integración con sistemas de registro, interfaces de usuario u otros entornos especializados.

Implementación avanzada de host E/S

Para escenarios más complejos, recomendamos extender la clase NonInteractiveIoHost como punto de partida. Este enfoque le permite aprovechar la implementación no interactiva existente y, al mismo tiempo, personalizar solo los comportamientos específicos que necesita modificar.

A continuación, se muestra un ejemplo de un host E/S personalizado que amplía la implementación base:

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}`); } }

Este enfoque es más fácil de mantener que implementar toda la interfaz IIoHost desde cero, ya que solo necesita anular los métodos específicos que requieren un comportamiento personalizado.

Integración con entornos diferentes

Integración de aplicaciones web

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 });

Integración con entornos de CI/CD

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 });

Prácticas recomendadas para la implementación del host E/S

Al implementar un host E/S personalizado, tenga en cuenta estas prácticas recomendadas:

  • Gestión de errores: implemente una gestión de errores sólida en sus métodos de host E/S para evitar que las fallas afecten a las operaciones de CDK.

  • Tiempos de espera: considere implementar tiempos de espera para las interacciones de los usuarios a fin de evitar esperas indefinidas.

  • Registro: almacene los mensajes importantes en registros para solucionar problemas, en especial en entornos no interactivos.

  • Respuestas predeterminadas: proporcione respuestas predeterminadas razonables para entornos automatizados en los que la interacción del usuario no sea posible.

  • Indicación de progreso: en el caso de operaciones de larga duración, proporciona indicadores de progreso claros para mejorar la experiencia del usuario.

El siguiente ejemplo demuestra estas prácticas recomendadas mediante la implementación de un host E/S personalizado con gestión de errores, tiempos de espera para las interacciones de los usuarios y un registro adecuado. Esta implementación es adecuada para aplicaciones interactivas en las que es necesario equilibrar la capacidad de respuesta del usuario con un funcionamiento fiable:

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 });

Solución de problemas

Consideraciones al implementar un host E/S personalizado:

  • Rechazos de promesas no gestionados: asegúrese de que todas las operaciones asincrónicas se gestionen correctamente con bloques try/catch.

  • Espera infinita: implementa tiempos de espera para todas las interacciones de los usuarios para evitar que la aplicación se bloquee.

  • Niveles de mensajes faltantes: prepárese para gestionar los niveles nuevos de mensajes que puedan agregarse en versiones futuras de CDK.

  • Respuestas incoherentes: asegúrese de que la implementación de requestResponse devuelva los valores en el formato esperado.

El siguiente ejemplo demuestra un enfoque sólido para gestionar los niveles de mensajes, que incluye un manejo correcto de los tipos de mensajes desconocidos que podrían introducirse en versiones futuras de CDK. Esta implementación garantiza que su host E/S siga siendo compatible con las actualizaciones de CDK y, al mismo tiempo, mantenga un registro adecuado:

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 });