Ir al contenido

Blog

Migración desde AWS PDK

Esta guía te acompaña a través de un ejemplo de migración de un proyecto AWS PDK al Nx Plugin para AWS, además de proporcionar orientación general sobre este tema.

Migrar al Nx Plugin para AWS proporciona los siguientes beneficios sobre PDK:

  • Compilaciones más rápidas
  • Más fácil de usar (UI y CLI)
  • Amigable con vibe-coding (¡prueba nuestro servidor MCP!)
  • Tecnologías más modernas
  • Desarrollo local de API y sitios web
  • Más control (modifica archivos generados para adaptarlos a tu caso de uso)
  • ¡Y más!

Ejemplo de Migración: Aplicación de Lista de Compras

Sección titulada «Ejemplo de Migración: Aplicación de Lista de Compras»

En esta guía, usaremos la Aplicación de Lista de Compras del Tutorial de PDK como nuestro proyecto objetivo a migrar. Sigue los pasos en ese tutorial para crear el proyecto objetivo si deseas seguir la guía tú mismo.

La aplicación de lista de compras consiste en los siguientes tipos de proyecto PDK:

  • MonorepoTsProject
  • TypeSafeApiProject
  • CloudscapeReactTsWebsiteProject
  • InfrastructureTsProject

Para comenzar, crearemos un nuevo espacio de trabajo para nuestro nuevo proyecto. Aunque es más extremo que una migración in situ, este enfoque nos da el resultado final más limpio. Crear un espacio de trabajo Nx es equivalente a usar el MonorepoTsProject de PDK:

Terminal window
pnpm create @aws/nx-workspace@1.0.0-rc.47 shopping-list --iac=cdk

Abre el directorio shopping-list que este comando crea en tu IDE favorito.

El TypeSafeApiProject utilizado en la aplicación de lista de compras hizo uso de:

  • Smithy como lenguaje de modelado
  • TypeScript para implementar operaciones
  • Generación de hooks de TypeScript para integrar con un sitio web de react

Por lo tanto, podemos usar el generador ts#smithy-api para proporcionar funcionalidad equivalente.

Ejecuta el generador ts#api con framework establecido en smithy para configurar tu proyecto de api en packages/api:

Terminal window
pnpm nx g @aws/nx-plugin:ts#api --name=api --framework=smithy --namespace=com.aws --auth=iam --no-interactive
También puede realizar una ejecución en seco para ver qué archivos se cambiarían
Terminal window
pnpm nx g @aws/nx-plugin:ts#api --name=api --framework=smithy --namespace=com.aws --auth=iam --no-interactive --dry-run

Notarás que esto genera un proyecto model, así como un proyecto backend. El proyecto model contiene tu modelo Smithy, y backend contiene tu implementación del servidor.

El backend utiliza el Smithy Server Generator for TypeScript. Exploraremos esto más a fondo a continuación.

Ahora que tenemos la estructura básica para nuestro proyecto de API Smithy, podemos migrar el modelo:

  1. Elimina los archivos Smithy de ejemplo generados en packages/api/model/src

  2. Copia tu modelo del directorio packages/api/model/src/main/smithy del proyecto PDK al directorio packages/api/model/src de tu nuevo proyecto.

  3. Actualiza el nombre del servicio y el espacio de nombres en smithy-build.json para que coincidan con la aplicación PDK:

    smithy-build.json
    "plugins": {
    "openapi": {
    "service": "com.aws#MyApi",
    ...
  4. Actualiza el servicio en main.smithy para agregar el error ValidationException, que es requerido al usar el Smithy TypeScript Server SDK.

    main.smithy
    use smithy.framework#ValidationException
    /// My Shopping List API
    @restJson1
    service MyApi {
    version: "1.0"
    operations: [
    GetShoppingLists
    PutShoppingList
    DeleteShoppingList
    ]
    errors: [
    BadRequestError
    NotAuthorizedError
    InternalFailureError
    ValidationException
    ]
    }
  5. Agrega un archivo extensions.smithy a packages/api/model/src donde definiremos un trait que proporciona información de paginación al cliente generado:

    extensions.smithy
    $version: "2"
    namespace com.aws
    use smithy.openapi#specificationExtension
    @trait
    @specificationExtension(as: "x-cursor")
    structure cursor {
    inputToken: String
    enabled: Boolean
    }
  6. Agrega el nuevo trait @cursor a la operación GetShoppingLists en get-shopping-lists.smithy:

    operations/get-shopping-lists.smithy
    @readonly
    @http(method: "GET", uri: "/shopping-list")
    @paginated(inputToken: "nextToken", outputToken: "nextToken", pageSize: "pageSize", items: "shoppingLists")
    @cursor(inputToken: "nextToken")
    @handler(language: "typescript")
    operation GetShoppingLists {
    input := with [PaginatedInputMixin] {
    @httpQuery("shoppingListId")
    shoppingListId: ShoppingListId
    }

    Cualquier operación @paginated también debe usar @cursor si estás utilizando el generador de cliente proporcionado por el Nx Plugin for AWS (a través del generador api-connection).

  7. Finalmente, elimina el trait @handler de todas las operaciones ya que esto no es compatible con el Nx Plugin for AWS. Usando ts#smithy-api, no necesitamos las construcciones CDK de funciones lambda generadas automáticamente ni los objetivos de empaquetado generados por este trait, ya que usamos un solo paquete para todas las funciones lambda.

En este punto, ejecutemos una compilación para verificar los cambios de nuestro modelo y asegurarnos de tener algo de código de servidor generado con el que trabajar. Habrá algunas fallas en el proyecto backend (@shopping-list/api) pero las abordaremos a continuación.

Terminal window
pnpm nx run-many --target build

Puedes considerar el proyecto api/backend como algo equivalente al proyecto api/handlers/typescript de Type Safe API.

Una de las principales diferencias entre Type Safe API y el generador ts#smithy-api es que los manejadores se implementan usando el Smithy Server Generator for TypeScript, en lugar de los envoltorios de manejadores generados propios de Type Safe API (que se encuentran en el proyecto api/generated/typescript/runtime).

Los manejadores lambda de la aplicación de lista de compras dependen del paquete @aws-sdk/client-dynamodb, así que instalémoslo en el proyecto @shopping-list/api:

Terminal window
pnpm add @aws-sdk/client-dynamodb --filter api

Luego, copiemos el archivo handlers/src/dynamo-client.ts del proyecto PDK a backend/src/operations para que esté disponible para nuestros manejadores.

El generador ts#smithy-api crea un ejemplo de operación Echo. Dado que eliminamos esto de nuestro modelo, elimina el manejador correspondiente en backend/src/operations/echo.ts. Registraremos nuestras operaciones migradas en service.ts más adelante.

Para migrar los manejadores, puedes seguir estos pasos generales:

  1. Copia el manejador del directorio packages/api/handlers/typescript/src de tu proyecto PDK al directorio packages/api/backend/src/operations de tu nuevo proyecto.

  2. Elimina las importaciones de my-api-typescript-runtime y en su lugar importa el tipo de operación del TypeScript Server SDK generado, así como el ServiceContext por ejemplo:

    import {
    deleteShoppingListHandler,
    DeleteShoppingListChainedHandlerFunction,
    INTERCEPTORS,
    Response,
    LoggingInterceptor,
    } from 'myapi-typescript-runtime';
    import { DeleteShoppingList as DeleteShoppingListOperation } from '../generated/ssdk/index.js';
    import { ServiceContext } from '../context.js';
  3. Elimina la exportación del envoltorio del manejador

    export const handler = deleteShoppingListHandler(
    ...INTERCEPTORS,
    deleteShoppingList,
    );
  4. Actualiza la firma de tu manejador de operación para usar el SSDK:

    export const deleteShoppingList: DeleteShoppingListChainedHandlerFunction = async (request) => {
    export const DeleteShoppingList: DeleteShoppingListOperation<ServiceContext> = async (input, ctx) => {
  5. Reemplaza el uso del LoggingInterceptor con ctx.logger. (También aplica a los interceptores de métricas y rastreo):

    LoggingInterceptor.getLogger(request).info('...');
    ctx.logger.info('...');
  6. Actualiza las referencias a los parámetros de entrada. Dado que el SSDK proporciona tipos que coinciden exactamente con tu modelo Smithy (en lugar de agrupar los parámetros de ruta/consulta/encabezado por separado del parámetro del cuerpo), actualiza cualquier referencia de entrada en consecuencia:

    const shoppingListId = request.input.requestParameters.shoppingListId;
    const shoppingListId = input.shoppingListId;
  7. Elimina el uso de Response. En su lugar, simplemente devolvemos objetos simples en el SSDK.

    return Response.success({ shoppingListId });
    return { shoppingListId };

    También ya no lanzamos ni devolvemos Response, en su lugar lanzamos los errores generados del SSDK:

    throw Response.badRequest({ message: 'oh no' });
    return Response.badRequest({ message: 'oh no' });
    import { BadRequestError } from '../generated/ssdk/index.js';
    throw new BadRequestError({ message: 'oh no' });
  8. Actualiza cualquier importación para usar la sintaxis ESM, es decir, agregando la extensión .js a las importaciones relativas.

  9. Agrega la operación a service.ts

    service.ts
    import { ServiceContext } from './context.js';
    import { MyApiService } from './generated/ssdk/index.js';
    import { DeleteShoppingList } from './operations/delete-shopping-list.js';
    import { GetShoppingLists } from './operations/get-shopping-lists.js';
    import { PutShoppingList } from './operations/put-shopping-list.js';
    // Register operations to the service here
    export const Service: MyApiService<ServiceContext> = {
    PutShoppingList,
    GetShoppingLists,
    DeleteShoppingList,
    };
Haz clic aquí para ver ejemplos completos de antes/después para las tres operaciones de lista de compras del tutorial

Generamos el proyecto de API Smithy con el nombre api inicialmente ya que queríamos que se agregara a packages/api para mantener la coherencia con el proyecto PDK. Dado que nuestra API Smithy ahora define service MyApi en lugar de service Api, necesitamos actualizar cualquier instancia de getApiServiceHandler con getMyApiServiceHandler.

Realiza este cambio en handler.ts:

packages/api/backend/src/handler.ts
import { getApiServiceHandler } from './generated/ssdk/index.js';
import { getMyApiServiceHandler } from './generated/ssdk/index.js';
process.env.POWERTOOLS_METRICS_NAMESPACE = 'Api';
process.env.POWERTOOLS_SERVICE_NAME = 'Api';
const tracer = new Tracer();
const logger = new Logger();
const metrics = new Metrics();
const serviceHandler = getApiServiceHandler(Service);
const serviceHandler = getMyApiServiceHandler(Service);

Y en local-server.ts:

packages/api/backend/src/local-server.ts
import { getApiServiceHandler } from './generated/ssdk/index.js';
import { getMyApiServiceHandler } from './generated/ssdk/index.js';
const PORT = 3001;
const tracer = new Tracer();
const logger = new Logger();
const metrics = new Metrics();
const serviceHandler = getApiServiceHandler(Service);
const serviceHandler = getMyApiServiceHandler(Service);

Además, actualiza packages/api/backend/project.json y actualiza metadata.apiName a my-api:

packages/api/backend/project.json
"metadata": {
"generator": "ts#smithy-api",
"apiName": "api",
"apiName": "my-api",
"auth": "iam",
"modelProject": "@shopping-list/api-model",
"ports": [3001]
},

Ahora podemos compilar el proyecto para verificar que la migración ha funcionado hasta ahora:

Terminal window
pnpm nx run-many --target build

El CloudscapeReactTsWebsiteProject utilizado en la aplicación de lista de compras configuró un sitio web React con CloudScape y autenticación Cognito integrada.

Este tipo de proyecto aprovechaba create-react-app, que ahora está obsoleto. Para migrar el sitio web en esta guía, utilizaremos el generador ts#website, que utiliza tecnologías más modernas y compatibles, específicamente Vite.

Como parte de la migración, también pasaremos del React Router configurado de PDK a TanStack Router, que agrega seguridad de tipos adicional al enrutamiento del sitio web.

Ejecuta el generador ts#website con framework establecido en react para configurar tu proyecto de sitio web en packages/website. Dado que la aplicación de lista de compras está construida con componentes CloudScape, también establecemos ux en cloudscape (el valor predeterminado es shadcn):

Terminal window
pnpm nx g @aws/nx-plugin:ts#website --name=website --framework=react --ux=cloudscape --no-interactive
También puede realizar una ejecución en seco para ver qué archivos se cambiarían
Terminal window
pnpm nx g @aws/nx-plugin:ts#website --name=website --framework=react --ux=cloudscape --no-interactive --dry-run

El generador de sitio web React anterior no incluye autenticación cognito por defecto como CloudscapeReactTsWebsiteProject, en su lugar se agrega explícitamente a través del generador ts#website#auth.

Terminal window
pnpm nx g @aws/nx-plugin:ts#website#auth --project=website --cognitoDomain=shopping-list --no-interactive
También puede realizar una ejecución en seco para ver qué archivos se cambiarían
Terminal window
pnpm nx g @aws/nx-plugin:ts#website#auth --project=website --cognitoDomain=shopping-list --no-interactive --dry-run

Esto agrega componentes React que gestionan las redirecciones apropiadas para garantizar que los usuarios inicien sesión utilizando la interfaz de usuario alojada de Cognito. Esto también agrega una construcción CDK para implementar los recursos de Cognito en packages/common/constructs, llamada UserIdentity.

En PDK podías pasar los proyectos Projen proporcionados entre sí para activar la generación de código de integración. Esto se usó en la aplicación de lista de compras para configurar el sitio web para poder integrarse con la API.

Con el Nx Plugin for AWS, la integración de API es compatible a través del generador connection. A continuación, usamos este generador para que nuestro sitio web pueda invocar nuestra API Smithy:

Terminal window
pnpm nx g @aws/nx-plugin:connection --sourceProject=website --targetProject=api --no-interactive
También puede realizar una ejecución en seco para ver qué archivos se cambiarían
Terminal window
pnpm nx g @aws/nx-plugin:connection --sourceProject=website --targetProject=api --no-interactive --dry-run

Esto genera los proveedores de cliente necesarios y los objetivos de compilación para que tu sitio web llame a tu API a través de un cliente TypeScript generado.

El CloudscapeReactTsWebsiteProject incluía automáticamente una dependencia de @aws-northstar/ui que se usa en nuestra aplicación de lista de compras, así que la agregamos al proyecto @shopping-list/website:

Terminal window
pnpm add @aws-northstar/ui --filter website

@aws-northstar/ui incluye un componente de editor de código que depende de ace-builds, usando una importación específica de webpack que Vite no puede resolver. Dado que nuestra aplicación de lista de compras no usa este componente, lo excluimos del paquete agregándolo a la configuración external dentro de las opciones build existentes en packages/website/vite.config.mts:

packages/website/vite.config.mts
build: {
outDir: '../../dist/packages/website/bundle',
emptyOutDir: true,
reportCompressedSize: true,
commonjsOptions: {
transformMixedEsModules: true,
},
rollupOptions: {
external: ['ace-builds/webpack-resolver'],
},
},

La aplicación de lista de compras tiene un componente llamado CreateItem, y dos páginas, ShoppingList y ShoppingLists. Migraremos estos al nuevo sitio web, haciendo algunos ajustes ya que estamos usando TanStack Router y el generador de código de cliente TypeScript del Nx Plugin for AWS.

  1. Copia packages/website/src/components/CreateItem/index.tsx del proyecto PDK a la misma ubicación exacta en el nuevo proyecto.

  2. Copia packages/website/src/pages/ShoppingLists/index.tsx a packages/website/src/routes/index.tsx, ya que ShoppingLists es nuestra página de inicio y usamos enrutamiento basado en archivos con TanStack router.

  3. Copia packages/website/src/pages/ShoppingList/index.tsx a packages/website/src/routes/$shoppingListId.tsx, ya que ShoppingList era la página que queremos mostrar en la ruta /:shoppingListId.

Ten en cuenta que ahora tendrás algunos errores de compilación visibles en tu IDE, necesitaremos hacer algunos cambios más para adaptarnos al nuevo marco, que se describen a continuación.

Dado que estamos usando enrutamiento basado en archivos, podemos usar el servidor de desarrollo local del sitio web para gestionar la generación automática de la configuración de rutas.

Iniciemos el servidor del sitio web local:

Terminal window
pnpm nx dev website

Verás algunos errores, pero el servidor del sitio web local debería iniciarse en el puerto 4200, así como el servidor de API Smithy local en el puerto 3001.

Sigue los pasos a continuación en routes/index.tsx y routes/$shoppingListId.tsx para migrar a TanStack Router:

  1. Agrega createFileRoute para registrar cada ruta:

    import { createFileRoute } from "@tanstack/react-router";
    ...
    export default ShoppingLists;
    export const Route = createFileRoute('/')({
    component: ShoppingLists,
    });

    Después de guardar el archivo, notarás que los errores de tipo con la llamada a createFileRoute han desaparecido.

  2. Reemplaza el hook useNavigate.

    Actualiza la importación:

    import { useNavigate } from 'react-router-dom';
    import { useNavigate } from '@tanstack/react-router';

    Actualiza las llamadas al método navigate (devuelto por useNavigate) para pasar las rutas con seguridad de tipos:

    navigate(`/${cell.shoppingListId}`);
    navigate({
    to: '/$shoppingListId',
    params: { shoppingListId: cell.shoppingListId },
    });
  3. Reemplaza el hook useParams.

    Elimina la importación:

    import { useParams } from 'react-router-dom';

    Actualiza las llamadas a useParams con el hook proporcionado por la Route creada anteriormente. ¡Ahora son seguras de tipos!

    const { shoppingListId } = useParams();
    const { shoppingListId } = Route.useParams();

Dado que nuestros archivos de ruta no están tan profundamente anidados en el árbol de archivos como lo estaban en nuestro proyecto PDK, necesitamos corregir la importación de CreateItem tanto en routes/index.tsx como en routes/$shoppingListId.tsx:

import CreateItem from "../../components/CreateItem";
import CreateItem from "../components/CreateItem";

El AppLayoutContext también se proporciona en una ubicación ligeramente diferente en nuestro nuevo proyecto:

import { AppLayoutContext } from "../../layouts/App";
import { AppLayoutContext } from "../components/AppLayout";

Migrar para usar el nuevo Cliente TypeScript Generado

Sección titulada «Migrar para usar el nuevo Cliente TypeScript Generado»

¡Nos estamos acercando ahora! A continuación, necesitamos migrar para usar el cliente TypeScript proporcionado por el Nx Plugin for AWS, que tiene algunas mejoras en comparación con Type Safe API. Para lograr esto, sigue los pasos a continuación

  1. Importa el nuevo cliente y tipos generados en lugar de los antiguos, por ejemplo:

    import {
    ShoppingList,
    usePutShoppingList,
    useDeleteShoppingList,
    useGetShoppingLists,
    } from "myapi-typescript-react-query-hooks";
    import { ShoppingList } from "../generated/my-api/types.gen";
    import { useMyApi } from "../hooks/useMyApi";
    import { useInfiniteQuery, useMutation } from "@tanstack/react-query";

    Ten en cuenta que routes/$shoppingListId.tsx importa el tipo ShoppingList como _ShoppingList - en ese archivo debemos hacer lo mismo, pero nuevamente importando desde types.gen.

    Ten en cuenta también que importamos los hooks relevantes directamente desde @tanstack/react-query, ya que el cliente generado proporciona métodos para generar opciones para los hooks de TanStack query, en lugar de envoltorios de hooks.

  2. Instancia los nuevos hooks de TanStack Query, por ejemplo:

    const getShoppingLists = useGetShoppingLists({ pageSize: PAGE_SIZE });
    const putShoppingList = usePutShoppingList();
    const deleteShoppingList = useDeleteShoppingList();
    const api = useMyApi();
    const getShoppingLists = useInfiniteQuery(
    api.getShoppingLists.infiniteQueryOptions(
    { pageSize: PAGE_SIZE },
    { getNextPageParam: (p) => p.nextToken },
    ),
    );
    const putShoppingList = useMutation(api.putShoppingList.mutationOptions());
    const deleteShoppingList = useMutation(
    api.deleteShoppingList.mutationOptions(),
    );
  3. Elimina el envoltorio <operation>RequestContent para las llamadas a operaciones que aceptan parámetros en el cuerpo de la solicitud:

    await putShoppingList.mutateAsync({
    putShoppingListRequestContent: {
    name: item,
    },
    });

Quedan algunos errores por corregir debido a las diferencias entre TanStack Query v4 (usado por PDK) y v5 que el generador connection agregó:

  1. Reemplaza isLoading con isPending para mutaciones, por ejemplo:

    putShoppingList.isLoading
    putShoppingList.isPending
  2. La aplicación de lista de compras hizo uso del InfiniteQueryTable de @aws-northstar/ui que espera un tipo de TanStack Query v4. Esto en realidad funciona con consultas infinitas de v5, así que simplemente podemos suprimir el error de tipo:

    <InfiniteQueryTable
    query={getShoppingLists}
    query={getShoppingLists as any}

Ahora puedes visitar el sitio web local en http://localhost:4200/

¡El sitio web debería cargarse ahora que todo ha sido migrado! Dado que la única infraestructura de la que depende la aplicación de lista de compras además de API, Website e Identity es la tabla DynamoDB - si tienes una tabla DynamoDB llamada shopping_list en la región, y credenciales locales de AWS que pueden acceder a ella, ¡el sitio web será completamente funcional!

Si no, está bien, migraremos la infraestructura a continuación.

Haz clic aquí para ver ejemplos completos de antes/después para las dos páginas de lista de compras del tutorial

El último proyecto que necesitamos migrar para nuestra aplicación de lista de compras es el InfrastructureTsProject. Este es un proyecto TypeScript CDK, para el cual el equivalente en Nx Plugin for AWS es el generador ts#infra.

Además de los proyectos Projen, PDK también proporcionaba construcciones CDK de las cuales estos proyectos dependen. Migraremos la aplicación de lista de compras de estas construcciones CDK también, en favor de las generadas por Nx Plugin for AWS.

Generar un Proyecto de Infraestructura TypeScript CDK

Sección titulada «Generar un Proyecto de Infraestructura TypeScript CDK»

Ejecuta el generador ts#infra para configurar tu proyecto de infraestructura en packages/infra:

Terminal window
pnpm nx g @aws/nx-plugin:ts#infra --name=infra --no-interactive
También puede realizar una ejecución en seco para ver qué archivos se cambiarían
Terminal window
pnpm nx g @aws/nx-plugin:ts#infra --name=infra --no-interactive --dry-run

La aplicación de lista de compras PDK instanciaba las siguientes construcciones dentro del stack de la aplicación CDK:

  • DatabaseConstruct para la tabla DynamoDB que almacena las listas de compras
  • UserIdentity para recursos Cognito, importado directamente desde PDK
  • MyApi para desplegar la API Smithy, que usaba la construcción TypeScript CDK generada con integraciones con seguridad de tipos, dependiendo de la construcción CDK TypeSafeRestApi de PDK bajo el capó.
  • Website para desplegar el sitio web, envolviendo la construcción CDK StaticWebsite de PDK.

A continuación, migraremos cada una de estas al nuevo proyecto.

Copia packages/infra/src/stacks/application-stack.ts de la aplicación de lista de compras PDK a la misma ubicación exacta en tu nuevo proyecto. Verás algunos errores de TypeScript que abordaremos a continuación.

La aplicación de lista de compras PDK tenía una construcción Database en packages/src/constructs/database.ts. Copia esto a la misma ubicación exacta en tu nuevo proyecto.

Dado que Nx Plugin for AWS usa Checkov para pruebas de seguridad, que es un poco más estricto que PDK Nag, también necesitamos agregar algunas supresiones:

constructs/database.ts
import { suppressRules } from '@shopping-list/common-constructs';
...
suppressRules(
this.shoppingListTable,
['CKV_AWS_28', 'CKV_AWS_119'],
'Backup and KMS key not required for this project',
);

En application-stack.ts, actualiza la importación para DatabaseConstruct para usar sintaxis ESM:

stacks/application-stack.ts
import { DatabaseConstruct } from '../constructs/database';
import { DatabaseConstruct } from '../constructs/database.js';

La construcción UserIdentity generalmente puede intercambiarse sin cambios ajustando las importaciones.

import { UserIdentity } from "@aws/pdk/identity";
import { UserIdentity } from '@shopping-list/common-constructs';
...
const userIdentity = new UserIdentity(this, `${id}UserIdentity`);

Ten en cuenta que las construcciones subyacentes utilizadas por la nueva construcción UserIdentity se proporcionan directamente desde aws-cdk-lib, donde PDK usaba @aws-cdk/aws-cognito-identitypool-alpha.

La aplicación de lista de compras PDK tenía una construcción en constructs/apis/myapi.ts que instanciaba una construcción CDK que Type Safe API generaba a partir de tu modelo Smithy.

Además de esta construcción, dado que el proyecto PDK usaba el trait @handler, también se generaban construcciones CDK de funciones lambda generadas.

Al igual que Type Safe API, Nx Plugin for AWS proporciona seguridad de tipos para integraciones basadas en tu modelo Smithy, sin embargo, se logra de una manera mucho más simple y flexible. En lugar de generar una construcción CDK completa en tiempo de compilación, solo se generan “metadatos” mínimos, que packages/common/constructs/src/app/apis/api.ts usa de manera genérica. Puedes aprender más sobre cómo usar la construcción en la guía del generador ts#smithy-api.

Sigue los siguientes pasos:

  1. Instancia la construcción Api en application-stack.ts

    stacks/application-stack.ts
    import { MyApi } from "../constructs/apis/myapi";
    import { Api } from '@shopping-list/common-constructs';
    ...
    const myapi = new MyApi(this, "MyApi", {
    databaseConstruct,
    userIdentity,
    });
    const api = new Api(this, 'MyApi', {
    integrations: Api.defaultIntegrations(this).build(),
    });

    Observa aquí que usamos Api.defaultIntegrations(this).build() - el comportamiento predeterminado es crear una función lambda para cada operación en nuestra API, que es el mismo comportamiento que teníamos en myapi.ts.

  2. Otorga permisos para que las funciones lambda accedan a la tabla DynamoDB.

    En la aplicación de lista de compras PDK, el DatabaseConsruct se pasaba a MyApi, y este gestionaba la adición de los permisos relevantes a cada construcción de función generada. Haremos esto directamente en el archivo application-stack.ts accediendo a la propiedad integrations con seguridad de tipos de la construcción Api:

    stacks/application-stack.ts
    // Grant our lambda functions scoped access to call Dynamo
    databaseConstruct.shoppingListTable.grantReadData(
    api.integrations.getShoppingLists.handler,
    );
    [
    api.integrations.putShoppingList.handler,
    api.integrations.deleteShoppingList.handler,
    ].forEach((f) => databaseConstruct.shoppingListTable.grantWriteData(f));
  3. Otorga permisos para que los usuarios autenticados invoquen la API.

    Dentro del myapi.ts de la aplicación PDK, también se otorgaban permisos IAM a los usuarios autenticados para invocar la API. Haremos el equivalente en application-stack.ts:

    stacks/application-stack.ts
    api.grantInvokeAccess(userIdentity.identityPool.authenticatedRole);

Finalmente, agregamos la construcción Website de packages/common/constructs/src/app/static-websites/website.ts a application-stack.ts, ya que este es el equivalente de packages/infra/src/constructs/websites/website.ts de la aplicación de lista de compras PDK.

import { Website } from "../constructs/websites/website";
import { Website } from '@shopping-list/common-constructs';
...
new Website(this, "Website", {
userIdentity,
myapi,
});
new Website(this, 'Website');

Observa que no pasamos la identidad o la API al sitio web - la configuración en tiempo de ejecución se gestiona dentro de cada construcción proporcionada por Nx Plugin for AWS, donde UserIdentity y Api registran los valores necesarios, y Website gestiona su despliegue en /runtime-config.json en tu sitio web estático.

Construyamos el proyecto ahora que hemos migrado todas las partes relevantes de la base de código a nuestro nuevo proyecto.

Terminal window
pnpm nx run-many --target build

Ahora que tenemos nuestra base de código completamente migrada, podemos proceder a desplegarla. Hay dos caminos que podemos tomar en este punto.

El enfoque más simple es tratar esto como una aplicación completamente nueva, lo que significa que “empezaremos de nuevo” con una tabla DynamoDB y un Cognito User Pool nuevos, perdiendo todos los usuarios y sus listas de compras. Para este enfoque, simplemente:

  1. Elimina la tabla DynamoDB llamada shopping_list

  2. Despliega la nueva aplicación:

    Terminal window
    pnpm nx deploy infra shopping-list-infra-sandbox/*

🎉 ¡Y hemos terminado! 🎉

Migrar Recursos con Estado Existentes sin Interrupción (Más Complejo)

Sección titulada «Migrar Recursos con Estado Existentes sin Interrupción (Más Complejo)»

En realidad, es más probable que desees migrar los recursos de AWS existentes para que sean administrados por la nueva base de código, evitando cualquier tiempo de inactividad para tus clientes.

Para nuestra aplicación de lista de compras, los recursos con estado que nos importan son la tabla DynamoDB que contiene las listas de compras de nuestros usuarios, y el User Pool que contiene los detalles de todos nuestros usuarios registrados. Nuestro plan de alto nivel será retener estos dos recursos clave y moverlos para que sean administrados por nuestro nuevo stack, luego actualizar el DNS para que apunte a nuestro nuevo sitio web (y API si está expuesta a los clientes).

  1. Actualiza tu nueva aplicación para hacer referencia a los recursos existentes que deseas retener.

    Para la aplicación de lista de compras, hacemos esto para la tabla DynamoDB

    constructs/database.ts
    this.shoppingListTable = new Table(this, 'ShoppingList', {
    ...
    this.shoppingListTable = Table.fromTableName(
    this,
    'ShoppingList',
    'shopping_list',
    );

    Y para el Cognito User Pool

    packages/common/constructs/src/core/user-identity.ts
    this.userPool = this.createUserPool();
    this.userPool = UserPool.fromUserPoolId(
    this,
    'UserPool',
    '<your-user-pool-id>',
    );
  2. Construye y despliega la nueva aplicación:

    Terminal window
    pnpm nx run-many --target build
    Terminal window
    pnpm nx deploy infra shopping-list-infra-sandbox/*

    Ahora tenemos nuestra nueva aplicación levantada haciendo referencia a los recursos existentes, aún sin recibir tráfico.

  3. Realiza pruebas de integración completas para asegurar que la nueva aplicación funcione como se espera. Para la aplicación de lista de compras, carga el sitio web y verifica que puedas iniciar sesión y crear, ver, editar y eliminar listas de compras.

  4. Revierte los cambios que hacen referencia a los recursos existentes en tu nueva aplicación, pero no los despliegues todavía.

    constructs/database.ts
    this.shoppingListTable = new Table(this, 'ShoppingList', {
    ...
    this.shoppingListTable = Table.fromTableName(
    this,
    'ShoppingList',
    'shopping_list',
    );

    Y para el Cognito User Pool

    packages/common/constructs/src/core/user-identity.ts
    this.userPool = this.createUserPool();
    this.userPool = UserPool.fromUserPoolId(
    this,
    'UserPool',
    '<your-user-pool-id>',
    );

    Y luego ejecuta una construcción

    Terminal window
    pnpm nx run-many --target build
  5. Usa cdk import en la carpeta packages/infra de tu nueva aplicación para ver qué recursos se nos solicitará importar.

    New Application
    cd packages/infra
    pnpm exec cdk import shopping-list-infra-sandbox/Application --force

    Avanza por los prompts presionando enter. La importación fallará porque los recursos están administrados por otro stack - esto es esperado, solo hicimos este paso para confirmar qué recursos necesitaremos retener. Verás una salida como esta:

    Ventana de terminal
    shopping-list-infra-sandbox/Application/ApplicationUserIdentity/UserPool/smsRole/Resource (AWS::IAM::Role): enter RoleName (empty to skip)
    shopping-list-infra-sandbox/Application/ApplicationUserIdentity/UserPool/Resource (AWS::Cognito::UserPool): enter UserPoolId (empty to skip)
    shopping-list-infra-sandbox/Application/Database/ShoppingList/Resource (AWS::DynamoDB::Table): import with TableName=shopping_list (y/n) y

    Esto nos dice que en realidad hay 3 recursos que necesitaremos importar a nuestro nuevo stack.

  6. Actualiza tu antiguo proyecto PDK para establecer RemovalPolicy en RETAIN para los recursos descubiertos en el paso anterior. Al momento de escribir esto, este es el valor predeterminado tanto para el User Pool como para la tabla DynamoDB, pero necesitamos actualizarlo para el SMS Role que descubrimos arriba:

    application-stack.ts
    const userIdentity = new UserIdentity(this, `${id}UserIdentity`, {
    userPool,
    });
    const smsRole = userIdentity.userPool.node.findAll().filter(
    c => CfnResource.isCfnResource(c) &&
    c.node.path.includes('/smsRole/'))[0] as CfnResource;
    smsRole.applyRemovalPolicy(RemovalPolicy.RETAIN);
  7. Despliega tu proyecto PDK para que se apliquen las políticas de eliminación

    PDK Application
    cd packages/infra
    npx projen deploy
  8. Echa un vistazo a la consola de CloudFormation y registra los valores que se te solicitaron en el paso cdk import anterior

    1. El User Pool ID, ej. us-west-2_XXXXX
    2. El SMS Role Name, ej. infra-sandbox-UserIdentityUserPoolsmsRoleXXXXXX
  9. Actualiza tu proyecto PDK para hacer referencia a los recursos existentes en lugar de crearlos

    constructs/database.ts
    this.shoppingListTable = new Table(this, 'ShoppingList', {
    ...
    this.shoppingListTable = Table.fromTableName(
    this,
    'ShoppingList',
    'shopping_list',
    );

    Y para el Cognito User Pool

    application-stack.ts
    const userPool = UserPool.fromUserPoolId(
    this,
    'UserPool',
    '<your-user-pool-id>',
    );
    const userIdentity = new UserIdentity(this, `${id}UserIdentity`, {
    // PDK construct accepts UserPool not IUserPool, but this still works!
    userPool: userPool as any,
    });
  10. Despliega tu proyecto PDK nuevamente, esto significará que los recursos ya no están administrados por el stack de CloudFormation de nuestro proyecto PDK.

    PDK Application
    cd packages/infra
    npx projen deploy
  11. Ahora que los recursos no están administrados, podemos ejecutar cdk import en nuestra nueva aplicación para realizar realmente la importación:

    New Application
    cd packages/infra
    pnpm exec cdk import shopping-list-infra-sandbox/Application --force

    Ingresa los valores cuando se te solicite, la importación debería completarse exitosamente.

  12. Despliega la nueva aplicación nuevamente para asegurarte de que se realicen los cambios en estos recursos existentes (ahora administrados por tu nuevo stack):

    Terminal window
    pnpm nx deploy infra shopping-list-infra-sandbox/*
  13. Realiza una prueba completa de tu nueva aplicación nuevamente

  14. Actualiza los registros DNS para que apunten a tu nuevo sitio web (y API si es necesario).

    Recomendamos un enfoque gradual usando Weighted Routing de Route53, mediante el cual una fracción de las solicitudes se dirigen a la nueva aplicación para comenzar. A medida que monitoreas tus métricas, puedes aumentar el peso para la nueva aplicación hasta que no se envíe tráfico a tu antigua aplicación PDK.

    Si no tienes ningún DNS y usaste los dominios generados automáticamente para el sitio web y la API, siempre puedes considerar hacer proxy de las solicitudes (por ejemplo, a través de un CloudFront HTTP origin o API Gateway HTTP integration(s)).

  15. Monitorea las métricas de la aplicación PDK para asegurar que no haya tráfico, y finalmente destruye el antiguo stack de CloudFormation:

    Ventana de terminal
    cd packages/infra
    npx projen destroy

Eso fue un poco más complicado, ¡pero migramos exitosamente a nuestros usuarios sin problemas a la nueva aplicación! 🎉🎉🎉

Ahora tenemos los nuevos beneficios del Nx Plugin for AWS sobre PDK:

  • Construcciones más rápidas
  • Soporte para desarrollo local de API
  • Una base de código amigable para vibe-coding (¡prueba nuestro servidor MCP!)
  • Código cliente/servidor con tipado seguro más intuitivo
  • ¡Y más!

Esta sección proporciona orientación para características de PDK que no están cubiertas por el ejemplo de migración anterior.

Como regla general al pasar de PDK, recomendamos comenzar cualquier proyecto con un Espacio de Trabajo Nx, dadas sus similitudes con el Monorepo de PDK. También recomendamos usar nuestros generadores como las primitivas sobre las cuales construir cualquier nuevo tipo.

Terminal window
pnpm create @aws/nx-workspace my-project

CDK Graph construye gráficos de tus recursos CDK conectados, y proporcionó dos plugins:

El CDK Graph Diagram Plugin genera diagramas de arquitectura de AWS a partir de tu infraestructura CDK.

Para un enfoque determinístico similar, una alternativa viable es CDK-Dia.

Con los avances en IA Generativa, muchos modelos fundacionales son capaces de crear diagramas de alta calidad a partir de tu infraestructura CDK. Recomendamos probar el AWS Diagram MCP Server. Consulta esta publicación del blog para un tutorial.

El CDK Graph Threat Composer Plugin genera un Threat Composer inicial de modelo de amenazas a partir de tu código CDK.

Este plugin funcionaba simplemente filtrando un modelo de amenazas base que contenía amenazas de ejemplo, y filtrándolas según los recursos que tu stack utilizaba.

Si estás interesado en estas amenazas de ejemplo específicas, puedes copiar y filtrar el modelo de amenazas base, o usarlo como contexto para ayudar a un modelo fundacional a generar uno similar.

AWS Arch proporcionaba mapeos entre recursos de CloudFormation y sus iconos de arquitectura asociados para CDK Graph anteriormente.

Consulta la página de iconos de arquitectura de AWS para recursos relacionados con iconos. Diagrams también proporciona una forma de construir diagramas como código.

Si estabas usando esto directamente, ¡considera hacer un fork del proyecto y tomar propiedad del mismo!

PDK proporcionaba un PDKPipelineProject que configuraba un proyecto de infraestructura CDK y hacía uso de un constructo CDK que envolvía algunos recursos de CDK Pipelines.

Para migrar desde esto, puedes usar los constructos de CDK Pipelines directamente. Sin embargo, en la práctica es probable que sea más sencillo usar algo como GitHub actions o GitLab CI/CD, donde defines CDK Stages y ejecutas el comando deploy para el stage apropiado directamente.

PDK Nag envuelve CDK Nag, y proporciona un conjunto de reglas específicas para construir prototipos.

Para migrar desde PDK Nag, usa CDK Nag directamente. Si necesitas el mismo conjunto de reglas, puedes crear un “pack” propio siguiendo la documentación aquí.

Los componentes más comúnmente utilizados de Type Safe API están cubiertos en el ejemplo de migración anterior, sin embargo, hay otras características para las cuales los detalles de migración se encuentran a continuación.

El Nx Plugin for AWS admite APIs modeladas en Smithy, pero no aquellas modeladas directamente en OpenAPI. El generador ts#smithy-api es un buen punto de partida que luego puedes modificar. Puedes definir tu especificación OpenAPI en la carpeta src del proyecto model en lugar de Smithy, y modificar el build.Dockerfile para usar tu herramienta de generación de código deseada para clientes/servidores si no están disponibles en NPM. Si tus herramientas deseadas están en NPM, simplemente puedes instalarlas como dependencias de desarrollo en tu espacio de trabajo Nx y llamarlas directamente como objetivos de compilación de Nx.

Para backends type-safe modelados en OpenAPI, puedes considerar usar uno de los Generadores de Servidor de OpenAPI Generator. Estos no generarán directamente para AWS Lambda, pero puedes usar el AWS Lambda Web Adapter para cerrar la brecha para muchos de ellos.

Para clientes TypeScript, puedes usar el generador ts#website y el generador connection con un ejemplo de ts#api (con framework configurado como smithy) para ver cómo se generan e integran los clientes con un sitio web. Esto configura objetivos de compilación que generan clientes invocando nuestros generadores open-api#ts-client u open-api#ts-hooks. Puedes usar estos generadores tú mismo apuntándolos a tu Especificación OpenAPI.

Para otros lenguajes, también puedes ver si alguno de los generadores de OpenAPI Generator se ajusta a tus necesidades.

También puedes construir un generador personalizado usando el generador ts#nx-generator. Consulta la documentación de ese generador para obtener detalles sobre cómo generar código desde OpenAPI. Puedes usar las plantillas del Nx Plugin for AWS como punto de partida. También puedes incluso consultar las plantillas del código base de PDK para más inspiración, teniendo en cuenta que la estructura de datos sobre la que operan las plantillas es un poco diferente al Nx Plugin for AWS.

Para TypeSpec, la sección anterior para OpenAPI también aplica. Puedes comenzar generando un ts#smithy-api, instalar el compilador TypeSpec y los paquetes OpenAPI en tu espacio de trabajo Nx, y actualizar el objetivo compile del proyecto model para ejecutar tsp compile en su lugar, asegurándote de que genere una especificación OpenAPI en el directorio dist.

El enfoque recomendado sería usar el generador de servidor HTTP TypeSpec para JavaScript para generar tu código de servidor, ya que esto funciona directamente en tu modelo TypeSpec.

Puedes usar el AWS Lambda Web Adapter para ejecutar el servidor generado en AWS Lambda.

También puedes usar cualquiera de las opciones de OpenAPI anteriores.

TypeSpec tiene sus propios generadores de código para clientes en los tres lenguajes admitidos por Type Safe API:

La sección de OpenAPI anterior también aplica ya que TypeSpec puede compilar a OpenAPI.

El ejemplo de migración anterior describe la migración para usar el generador ts#smithy-api. Esta sección cubre las opciones para backends y clientes de Python y Java.

El generador de código Smithy para Java. Este tiene un generador de servidor Java así como un adaptador para ejecutar el servidor Java generado en AWS Lambda.

Smithy no tiene un generador de servidor para Python, por lo que necesitarás ir a través de OpenAPI. Consulta la sección anterior sobre APIs Modeladas con OpenAPI para opciones potenciales.

El generador de código Smithy para Java. Este tiene un generador de cliente Java.

Para clientes Python, puedes revisar Smithy Python.

Para TypeScript, revisa Smithy TypeScript, o usa el mismo enfoque que hemos tomado en ts#smithy-api yendo a través de OpenAPI (optamos por esto ya que nos da consistencia entre APIs tRPC, FastAPI y Smithy a través de hooks de TanStack Query).

Type Safe API proporcionaba un tipo de proyecto Projen llamado SmithyShapeLibraryProject que configuraba un proyecto que contenía modelos Smithy que podían ser reutilizados por múltiples APIs basadas en Smithy.

El equivalente es el generador smithy#project con type configurado como shapes:

Terminal window
pnpm nx g @aws/nx-plugin:smithy#project --name=my-shapes --type=shapes
También puede realizar una ejecución en seco para ver qué archivos se cambiarían
Terminal window
pnpm nx g @aws/nx-plugin:smithy#project --name=my-shapes --type=shapes --dry-run

Mueve las formas de tu SmithyShapeLibraryProject a la carpeta src del proyecto generado, luego consulta la guía del proyecto Smithy para saber cómo conectar la biblioteca como una dependencia del modelo de tu API.

Type Safe API proporcionaba los siguientes interceptores predeterminados:

  • Interceptores de registro, rastreo y métricas usando Powertools for AWS Lambda
  • Interceptor try-catch para manejar excepciones no capturadas
  • Interceptor CORS para devolver encabezados CORS

El generador ts#smithy-api instrumenta registro, rastreo y métricas con Powertools for AWS Lambda usando Middy. El comportamiento del interceptor try-catch está integrado en el Smithy TypeScript SSDK, y los encabezados CORS se agregan en handler.ts.

Para interceptores de registro, rastreo y métricas en cualquier lenguaje, usa Powertools for AWS Lambda directamente.

Para migrar interceptores personalizados, recomendamos usar las siguientes bibliotecas:

Type Safe API proporcionaba generación de documentación usando Redocly CLI. Esto es muy fácil de agregar a un proyecto existente una vez que lo hayas migrado como se indicó anteriormente.

  1. Instala el Redocly CLI

    Terminal window
    pnpm add -Dw @redocly/cli
  2. Agrega un objetivo de generación de documentación a tu proyecto model usando redocly build-docs, por ejemplo:

    model/project.json
    {
    ...
    "documentation": {
    "cache": true,
    "outputs": ["{workspaceRoot}/dist/{projectRoot}/documentation"],
    "executor": "nx:run-commands",
    "options": {
    "command": "redocly build-docs dist/packages/api/model/build/openapi/openapi.json --output=dist/packages/api/model/documentation/index.html",
    "cwd": "{workspaceRoot}"
    },
    "dependsOn": ["compile"]
    }
    }

También puedes considerar los generadores de documentación de OpenAPI Generator.

Type Safe API generaba mocks para ti dentro de su paquete de infraestructura generado.

Puedes migrar a JSON Schema Faker que puede crear los datos mock basados en JSON Schemas. Esto puede funcionar directamente en una especificación OpenAPI, y tiene una CLI que podrías ejecutar como parte de la compilación de tu proyecto model.

Puedes actualizar tu infraestructura CDK para leer el archivo JSON generado por JSON Schema Faker, y devolver la MockIntegration de API Gateway apropiada para una integración, basándote en el metadata.gen.ts generado (asumiendo que usaste el generador ts#smithy-api).

Type Safe API admitía la implementación de APIs con una mezcla de diferentes lenguajes en el backend. Esto también se puede lograr proporcionando “overrides” a las integraciones al instanciar tu constructo API en CDK:

application-stack.ts
const pythonLambdaHandler = new Function(this, 'PythonImplementation', {
runtime: Runtime.PYTHON_3_12,
...
});
new MyApi(this, 'MyApi', {
integrations: Api.defaultIntegrations(this)
.withOverrides({
echo: {
integration: new LambdaIntegration(pythonLambdaHandler),
handler: pythonLambdaHandler,
},
})
.build(),
});

Necesitarás “stub” tu servicio/enrutador para que tu servicio compile si usas el ts#smithy-api y el TypeScript Server SDK, por ejemplo:

service.ts
export const Service: ApiService<ServiceContext> = {
...
Echo: () => { throw new Error(`Not Implemented`); },
};

Type Safe API agregaba validación nativa de API Gateway para cuerpos de solicitud basados en tu especificación OpenAPI ya que usaba el constructo SpecRestApi internamente.

Con el generador ts#smithy-api, la validación es realizada por el Server SDK mismo. Esto es lo mismo para la mayoría de los generadores de servidor.

Si deseas implementar validación nativa de API Gateway, podrías hacerlo modificando packages/common/constructs/src/core/api/rest-api.ts para leer el JSON schema relevante para el cuerpo de solicitud de cada operación desde tu especificación OpenAPI.

Desafortunadamente no hay una ruta de migración directa para la API websocket de Type Safe API usando API Gateway y Lambda con desarrollo de API basado en modelos. Sin embargo, esta sección de la guía tiene como objetivo al menos ofrecer algunas ideas.

Considera usar AsyncAPI para modelar tu API en lugar de OpenAPI o TypeSpec ya que está diseñado para manejar APIs asíncronas. La Plantilla NodeJS de AsyncAPI puede generar un backend de websocket Node que podrías alojar en ECS por ejemplo.

También puedes considerar AppSync Events para infraestructura, y usar Powertools. ¡Esta publicación de blog vale la pena leer!

Otra opción es usar APIs GraphQL con websockets en AppSync, para lo cual tenemos un issue de GitHub al que puedes dar +1! Consulta la guía del desarrollador de AppSync para detalles y enlaces a proyectos de ejemplo.

También puedes considerar crear tus propios generadores de código que interpreten las mismas extensiones de proveedor que Type Safe API. Consulta la sección APIs Modeladas con OpenAPI para detalles sobre la construcción de generadores personalizados basados en OpenAPI. Puedes encontrar las plantillas que Type Safe API usa para los manejadores Lambda de API Gateway Websocket API aquí, y el cliente aquí.

También puedes considerar migrar para usar el generador ts#trpc-api para usar tRPC. Al momento de escribir esto, aún no tenemos soporte para suscripciones/streaming pero si esto es algo que necesitas, agrega un +1 a nuestro issue de GitHub que rastrea esto.

Smithy es agnóstico al protocolo, pero aún no tiene soporte para el protocolo Websocket, consulta este issue de GitHub que rastrea el soporte.

PDK soportaba infraestructura CDK escrita en Python y Java. No soportamos esto en el Nx Plugin for AWS al momento de escribir esto.

El camino recomendado sería migrar tu infraestructura CDK a TypeScript, o usar nuestros generadores y migrar el paquete de construcciones comunes a tu lenguaje deseado. Puedes usar IA Generativa para acelerar este tipo de migraciones, por ejemplo Kiro CLI. Puedes hacer que un agente de IA itere sobre la migración hasta que las plantillas de CloudFormation sintetizadas sean idénticas.

Lo mismo aplica para la infraestructura generada de Type Safe API en Python o Java - puedes traducir la construcción genérica rest-api.ts del paquete de construcciones comunes, e implementar tu propio generador de metadatos simple para tu lenguaje objetivo (consulta la sección APIs Modelled with OpenAPI).

Puedes usar el generador py#project para un proyecto base de Python al que agregar tu código CDK (y mover tu archivo cdk.json, agregando los targets relevantes). Puedes usar el plugin @nx/gradle de Nx para proyectos Java, o @jnxplus/nx-maven para Maven.

PDK fue construido sobre Projen. Projen y Nx Generators tienen diferencias bastante fundamentales, lo que significa que aunque es técnicamente posible combinarlos, es probable que sea un anti-patrón. Projen gestiona los archivos del proyecto como código de tal manera que no pueden ser modificados directamente, mientras que los generadores de Nx proporcionan archivos de proyecto una vez y luego el código puede ser modificado libremente.

Si desea continuar usando Projen, puede implementar los tipos de proyecto Projen deseados usted mismo. Para seguir los patrones del Nx Plugin for AWS, puede ejecutar nuestros generadores o examinar su código fuente en GitHub para ver cómo se construyen los tipos de proyecto deseados, e implementar las partes relevantes usando las primitivas de Projen.

Presentando el Nx Plugin for AWS MCP Server

En un panorama de desarrollo de software en rápida evolución, los asistentes de IA se han convertido en valiosos colaboradores en nuestro viaje de codificación. Muchos desarrolladores han adoptado lo que cariñosamente llamamos “vibe-coding” - la danza colaborativa entre la creatividad humana y la asistencia de IA. Como cualquier práctica emergente, viene con beneficios emocionantes y desafíos notables. Esta publicación presenta el Nx Plugin for AWS MCP Server, que mejora la experiencia de desarrollo asistido por IA al trabajar con productos y servicios de AWS.

El vibe-coding, la práctica de construir software colaborativamente con asistentes de IA, ha transformado cómo muchas organizaciones abordan el desarrollo de software. Describes lo que quieres construir, y tu asistente de IA ayuda a dar vida a tu visión, escribiendo código y pruebas, ejecutando comandos de compilación e iterando colaborativamente para completar tareas tanto grandes como pequeñas.

Este enfoque colaborativo ha acelerado significativamente los ciclos de desarrollo, ya que implementaciones complejas que anteriormente podrían tomar horas escribir manualmente, a menudo pueden completarse en minutos.

A pesar de sus beneficios, el vibe-coding viene con dificultades que pueden interrumpir tu flujo y llevar a la frustración. Las herramientas de IA pueden producir patrones inconsistentes a través de un proyecto, lo que puede crear dolores de cabeza de mantenimiento en el futuro. Sin orientación específica, la IA puede pasar por alto mejores prácticas específicas de AWS o consideraciones de seguridad importantes que los desarrolladores experimentados incorporarían naturalmente.

Sin una estructura de proyecto clara, el código asistido por IA puede volverse desorganizado y difícil de mantener. La IA puede crear implementaciones personalizadas para problemas que ya tienen soluciones establecidas, reinventando innecesariamente la rueda.

Estos desafíos pueden llevar a deuda técnica, vulnerabilidades de seguridad y frustración, especialmente al trabajar con varios servicios de AWS interconectados y no solo dentro de los límites de un único framework.

El Nx Plugin for AWS proporciona una base estructurada para construir aplicaciones de AWS utilizando las herramientas de monorepo de Nx. En lugar de comenzar con un lienzo en blanco, el plugin ofrece un framework consistente para la organización del proyecto.

El plugin asegura un scaffolding de proyecto consistente a través de generadores para tipos de proyectos comunes, lo que mantiene la integridad estructural en toda tu base de código. Incorpora plantillas preconfiguradas que siguen las mejores prácticas de AWS, ayudando a los desarrolladores a evitar errores comunes y problemas de seguridad. Las herramientas integradas proporcionan comandos incorporados para construir, probar y desplegar aplicaciones de AWS, y optimizan el flujo de trabajo de desarrollo a través de servidores de desarrollo locales. Además, aprovecha la poderosa gestión de dependencias de Nx para proyectos complejos, simplificando la gestión de monorepos.

Al proporcionar esta estructura, el Nx Plugin for AWS le da a los asistentes de IA una estructura clara dentro de la cual trabajar. En lugar de inventar patrones desde cero, los asistentes de IA pueden seguir convenciones establecidas, lo que lleva a una base de código más consistente y mantenible.

Model Context Protocol (MCP) es un estándar abierto que permite a los asistentes de IA interactuar con herramientas y recursos externos. El Nx Plugin for AWS MCP server extiende las capacidades de tu asistente de IA con conocimiento especializado sobre el Nx Plugin for AWS.

El MCP server proporciona información contextual sobre mejores prácticas, estructuras de proyecto disponibles y patrones de implementación específicos para el desarrollo de AWS. Permite que tus herramientas de IA creen espacios de trabajo y ejecuten generadores para hacer scaffolding de tipos de proyectos comunes. Esta conciencia contextual ayuda a la IA a hacer sugerencias más informadas que se alinean con patrones establecidos y evitan errores comunes.

En lugar de producir código que podría no alinearse con las mejores prácticas o que podría hacer referencia a características inexistentes, tu asistente de IA puede aprovechar el MCP server para sentar una base para tu proyecto. El resultado es una experiencia de desarrollo más determinista y confiable, donde puedes comenzar con una base sólida para los componentes centrales de tu proyecto y usar IA para completar la lógica de negocio.

Si estás interesado en explorar el desarrollo de AWS asistido por IA con más estructura y confiabilidad, prueba el Nx Plugin for AWS MCP Server. Puedes configurarlo en tu asistente de IA favorito (Kiro, Kiro CLI, Cline, Claude Code, etc.) con la siguiente configuración de MCP Server:

{
"mcpServers": {
"nx-plugin-for-aws": {
"command": "npx",
"args": ["-y", "@aws/nx-plugin-mcp"]
}
}
}

Para instrucciones detalladas, consulta nuestra guía de Construcción con IA.

Bienvenido al @aws/nx-plugin

¡Y estamos en vivo! 🚀

El Nx Plugin for AWS es un plugin de Nx que proporciona un conjunto de herramientas para simplificar el proceso de construcción e implementación de aplicaciones full-stack en AWS. Proporciona a los desarrolladores plantillas preconfiguradas tanto para código de aplicación como de IaC, reduciendo significativamente el tiempo dedicado a la configuración inicial. El plugin maneja la complejidad de la integración de servicios de AWS mientras mantiene flexibilidad para la personalización.

Los usuarios simplemente eligen los componentes que desean de la lista de generadores disponibles, proporcionan las opciones de configuración y hacen que el @aws/nx-plugin genere el código inicial requerido. Existen varios generadores dentro de este conjunto de herramientas que pueden crear APIs, sitios web, infraestructura e incluso hacer cosas más sofisticadas como integrar un frontend a un backend (¡incluyendo la actualización de archivos existentes mediante transformaciones AST!) con clientes con seguridad de tipos.

generator

Para obtener más información, comienza con nuestro tutorial de Dungeon Adventure, que cubre todos los componentes principales del plugin y debería darte una buena idea de cómo usarlo.

Estamos ansiosos por escuchar tus comentarios, ¡no dudes en publicar una discusión o crear un issue para hacernos saber lo que piensas y qué te gustaría ver a continuación!

¡Pruébalo!