Pular para o conteúdo

Blog

Migrando do AWS PDK

Este guia orienta você através de um exemplo de migração de um projeto AWS PDK para o Nx Plugin for AWS, além de fornecer orientações gerais sobre este tópico.

Migrar para o Nx Plugin for AWS oferece os seguintes benefícios em relação ao PDK:

  • Builds mais rápidos
  • Mais fácil de usar (UI e CLI)
  • Amigável para vibe-coding (experimente nosso servidor MCP!)
  • Tecnologias mais modernas
  • Desenvolvimento local de API e website
  • Mais controle (modifique arquivos fornecidos para se adequar ao seu caso de uso)
  • E muito mais!

Exemplo de Migração: Aplicação de Lista de Compras

Seção intitulada “Exemplo de Migração: Aplicação de Lista de Compras”

Neste guia, usaremos a Aplicação de Lista de Compras do Tutorial do PDK como nosso projeto alvo para migrar. Siga as etapas desse tutorial para criar o projeto alvo se desejar acompanhar você mesmo.

A aplicação de lista de compras consiste nos seguintes tipos de projeto PDK:

  • MonorepoTsProject
  • TypeSafeApiProject
  • CloudscapeReactTsWebsiteProject
  • InfrastructureTsProject

Para começar, criaremos um novo workspace para nosso novo projeto. Embora seja mais extremo do que uma migração no local, essa abordagem nos dá o resultado final mais limpo. Criar um workspace Nx é equivalente a usar o MonorepoTsProject do PDK:

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

Abra o diretório shopping-list que este comando cria no seu IDE favorito.

O TypeSafeApiProject usado na aplicação de lista de compras fez uso de:

  • Smithy como linguagem de modelagem
  • TypeScript para implementar operações
  • Geração de hooks TypeScript para integração com um site react

Portanto, podemos usar o gerador ts#smithy-api para fornecer funcionalidade equivalente.

Execute o gerador ts#api com framework definido como smithy para configurar seu projeto de api em packages/api:

Terminal window
pnpm nx g @aws/nx-plugin:ts#api --name=api --framework=smithy --namespace=com.aws --auth=iam --no-interactive
Você também pode realizar uma execução simulada para ver quais arquivos seriam alterados
Terminal window
pnpm nx g @aws/nx-plugin:ts#api --name=api --framework=smithy --namespace=com.aws --auth=iam --no-interactive --dry-run

Você notará que isso gera um projeto model, bem como um projeto backend. O projeto model contém seu modelo Smithy, e backend contém sua implementação de servidor.

O backend usa o Smithy Server Generator for TypeScript. Exploraremos isso mais adiante abaixo.

Agora que temos a estrutura básica para nosso projeto de API Smithy, podemos migrar o modelo:

  1. Exclua os arquivos Smithy de exemplo gerados em packages/api/model/src

  2. Copie seu modelo do diretório packages/api/model/src/main/smithy do projeto PDK para o diretório packages/api/model/src do seu novo projeto.

  3. Atualize o nome do serviço e o namespace em smithy-build.json para corresponder à aplicação PDK:

    smithy-build.json
    "plugins": {
    "openapi": {
    "service": "com.aws#MyApi",
    ...
  4. Atualize o serviço em main.smithy para adicionar o erro ValidationException, que é necessário ao usar o 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. Adicione um arquivo extensions.smithy em packages/api/model/src onde definiremos uma trait que fornece informações de paginação ao cliente gerado:

    extensions.smithy
    $version: "2"
    namespace com.aws
    use smithy.openapi#specificationExtension
    @trait
    @specificationExtension(as: "x-cursor")
    structure cursor {
    inputToken: String
    enabled: Boolean
    }
  6. Adicione a nova trait @cursor à operação GetShoppingLists em 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
    }

    Quaisquer operações @paginated também devem usar @cursor se você estiver usando o gerador de cliente fornecido pelo Nx Plugin for AWS (via o gerador api-connection).

  7. Finalmente, remova a trait @handler de todas as operações, pois isso não é suportado pelo Nx Plugin for AWS. Usando ts#smithy-api, não precisamos dos constructs CDK de função lambda gerados automaticamente e dos alvos de empacotamento gerados por essa trait, pois usamos um único pacote para todas as funções lambda.

Neste ponto, vamos executar uma compilação para verificar nossas alterações no modelo e garantir que temos algum código de servidor gerado para trabalhar. Haverá algumas falhas no projeto backend (@shopping-list/api), mas vamos resolver isso em seguida.

Terminal window
pnpm nx run-many --target build

Você pode considerar o projeto api/backend como algo equivalente ao projeto api/handlers/typescript do Type Safe API.

Uma das principais diferenças entre Type Safe API e o gerador ts#smithy-api é que os handlers são implementados usando o Smithy Server Generator for TypeScript, em vez dos próprios wrappers de handler gerados do Type Safe API (encontrados no projeto api/generated/typescript/runtime).

Os handlers lambda da aplicação de lista de compras dependem do pacote @aws-sdk/client-dynamodb, então vamos instalá-lo no projeto @shopping-list/api:

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

Em seguida, vamos copiar o arquivo handlers/src/dynamo-client.ts do projeto PDK para backend/src/operations para que esteja disponível para nossos handlers.

O gerador ts#smithy-api cria um exemplo de operação Echo. Como removemos isso do nosso modelo, exclua o handler correspondente em backend/src/operations/echo.ts. Registraremos nossas operações migradas em service.ts mais adiante abaixo.

Para migrar os handlers, você pode seguir estas etapas gerais:

  1. Copie o handler do diretório packages/api/handlers/typescript/src do seu projeto PDK para o diretório packages/api/backend/src/operations do seu novo projeto.

  2. Remova as importações de my-api-typescript-runtime e, em vez disso, importe o tipo de operação do TypeScript Server SDK gerado, bem como o ServiceContext, por exemplo:

    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. Exclua a exportação do wrapper do handler

    export const handler = deleteShoppingListHandler(
    ...INTERCEPTORS,
    deleteShoppingList,
    );
  4. Atualize a assinatura do seu handler de operação para usar o SSDK:

    export const deleteShoppingList: DeleteShoppingListChainedHandlerFunction = async (request) => {
    export const DeleteShoppingList: DeleteShoppingListOperation<ServiceContext> = async (input, ctx) => {
  5. Substitua o uso do LoggingInterceptor por ctx.logger. (Também se aplica aos interceptors de métricas e rastreamento):

    LoggingInterceptor.getLogger(request).info('...');
    ctx.logger.info('...');
  6. Atualize as referências aos parâmetros de entrada. Como o SSDK fornece tipos que correspondem exatamente ao seu modelo Smithy (em vez de agrupar parâmetros de caminho/consulta/cabeçalho separadamente do parâmetro de corpo), atualize quaisquer referências de entrada de acordo:

    const shoppingListId = request.input.requestParameters.shoppingListId;
    const shoppingListId = input.shoppingListId;
  7. Remova o uso de Response. Em vez disso, apenas retornamos objetos simples no SSDK.

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

    Também não lançamos ou retornamos mais Response, em vez disso, lançamos os erros gerados do 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. Atualize quaisquer importações para usar a sintaxe ESM, ou seja, adicionando a extensão .js às importações relativas.

  9. Adicione a operação 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,
    };
Clique aqui para exemplos completos de antes/depois para as três operações da lista de compras do tutorial

Geramos o projeto Smithy API com o nome api inicialmente, pois queríamos que fosse adicionado a packages/api para consistência com o projeto PDK. Como nossa Smithy API agora define service MyApi em vez de service Api, precisamos atualizar quaisquer instâncias de getApiServiceHandler com getMyApiServiceHandler.

Faça essa alteração em 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);

E em 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);

Além disso, atualize packages/api/backend/project.json e atualize metadata.apiName para 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]
},

Agora podemos compilar o projeto para verificar se a migração funcionou até agora:

Terminal window
pnpm nx run-many --target build

O CloudscapeReactTsWebsiteProject usado na aplicação de lista de compras configurou um website React com CloudScape e autenticação Cognito integrados.

Este tipo de projeto aproveitava create-react-app, que agora está obsoleto. Para migrar o website neste guia, usaremos o gerador ts#website, que usa tecnologias mais modernas e suportadas, nomeadamente Vite.

Como parte da migração, também migraremos do React Router configurado pelo PDK para o TanStack Router, que adiciona segurança de tipo adicional ao roteamento do website.

Execute o gerador ts#website com framework definido como react para configurar seu projeto de website em packages/website. Como a aplicação de lista de compras é construída com componentes CloudScape, também definimos ux como cloudscape (o padrão é shadcn):

Terminal window
pnpm nx g @aws/nx-plugin:ts#website --name=website --framework=react --ux=cloudscape --no-interactive
Você também pode realizar uma execução simulada para ver quais arquivos seriam alterados
Terminal window
pnpm nx g @aws/nx-plugin:ts#website --name=website --framework=react --ux=cloudscape --no-interactive --dry-run

O gerador de website React acima não inclui autenticação cognito por padrão como o CloudscapeReactTsWebsiteProject, em vez disso, é adicionado explicitamente através do gerador ts#website#auth.

Terminal window
pnpm nx g @aws/nx-plugin:ts#website#auth --project=website --cognitoDomain=shopping-list --no-interactive
Você também pode realizar uma execução simulada para ver quais arquivos seriam alterados
Terminal window
pnpm nx g @aws/nx-plugin:ts#website#auth --project=website --cognitoDomain=shopping-list --no-interactive --dry-run

Isso adiciona componentes React que gerenciam os redirecionamentos apropriados para garantir que os usuários façam login usando a UI hospedada do Cognito. Isso também adiciona um construto CDK para implantar os recursos do Cognito em packages/common/constructs, chamado UserIdentity.

No PDK, você podia passar os projetos Projen fornecidos uns aos outros para acionar a geração de código de integração. Isso foi usado na aplicação de lista de compras para configurar o website para poder integrar com a API.

Com o Nx Plugin for AWS, a integração de API é suportada através do gerador connection. Em seguida, usamos este gerador para que nosso website possa invocar nossa API Smithy:

Terminal window
pnpm nx g @aws/nx-plugin:connection --sourceProject=website --targetProject=api --no-interactive
Você também pode realizar uma execução simulada para ver quais arquivos seriam alterados
Terminal window
pnpm nx g @aws/nx-plugin:connection --sourceProject=website --targetProject=api --no-interactive --dry-run

Isso gera os provedores de cliente necessários e alvos de build para que seu website chame sua API através de um cliente TypeScript gerado.

O CloudscapeReactTsWebsiteProject incluía automaticamente uma dependência em @aws-northstar/ui que é usada em nossa aplicação de lista de compras, então a adicionamos ao projeto @shopping-list/website:

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

@aws-northstar/ui inclui um componente de editor de código que depende de ace-builds, usando uma importação específica do webpack que o Vite não consegue resolver. Como nossa aplicação de lista de compras não usa este componente, o excluímos do bundle adicionando-o à configuração external dentro das opções build existentes em 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'],
},
},

A aplicação de lista de compras tem um componente chamado CreateItem e duas páginas, ShoppingList e ShoppingLists. Vamos migrá-los para o novo website, fazendo alguns ajustes, já que estamos usando TanStack Router e o gerador de código de cliente TypeScript do Nx Plugin for AWS.

  1. Copie packages/website/src/components/CreateItem/index.tsx do projeto PDK para o mesmo local exato no novo projeto.

  2. Copie packages/website/src/pages/ShoppingLists/index.tsx para packages/website/src/routes/index.tsx, já que ShoppingLists é nossa página inicial e usamos roteamento baseado em arquivos com TanStack router.

  3. Copie packages/website/src/pages/ShoppingList/index.tsx para packages/website/src/routes/$shoppingListId.tsx, já que ShoppingList era a página que queremos mostrar na rota /:shoppingListId.

Observe que agora você terá alguns erros de build visíveis no seu IDE, precisaremos fazer mais algumas alterações para se adequar ao novo framework, descritas abaixo.

Como estamos usando roteamento baseado em arquivos, podemos usar o servidor de desenvolvimento local do website para gerenciar automaticamente a geração da configuração de rotas.

Vamos iniciar o servidor local do website:

Terminal window
pnpm nx dev website

Você verá alguns erros, mas o servidor local do website deve iniciar na porta 4200, assim como o servidor local da API Smithy na porta 3001.

Siga as etapas abaixo em ambos routes/index.tsx e routes/$shoppingListId.tsx para migrar para o TanStack Router:

  1. Adicione createFileRoute para registrar cada rota:

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

    Depois de salvar o arquivo, você notará que os erros de tipo com a chamada para createFileRoute desapareceram.

  2. Substitua o hook useNavigate.

    Atualize a importação:

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

    Atualize as chamadas para o método navigate (retornado por useNavigate) para passar as rotas com segurança de tipo:

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

    Remova a importação:

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

    Atualize as chamadas para useParams com o hook fornecido pela Route criada acima. Agora eles têm segurança de tipo!

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

Como nossos arquivos de rota não estão tão profundamente aninhados na árvore de arquivos como estavam em nosso projeto PDK, precisamos corrigir a importação de CreateItem em ambos routes/index.tsx e routes/$shoppingListId.tsx:

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

O AppLayoutContext também é fornecido em um local ligeiramente diferente em nosso novo projeto:

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

Estamos chegando mais perto agora! Em seguida, precisamos migrar para usar o cliente TypeScript fornecido pelo Nx Plugin for AWS, que tem algumas melhorias em comparação com Type Safe API. Para conseguir isso, siga as etapas abaixo

  1. Importe o novo cliente e tipos gerados em vez dos antigos, por exemplo:

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

    Observe que routes/$shoppingListId.tsx importa o tipo ShoppingList como _ShoppingList - nesse arquivo devemos fazer o mesmo, mas novamente importando de types.gen.

    Observe também que importamos os hooks relevantes diretamente de @tanstack/react-query, já que o cliente gerado fornece métodos para gerar opções para hooks TanStack query, em vez de wrappers de hooks.

  2. Instancie os novos hooks TanStack Query, por exemplo:

    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. Remova o wrapper <operation>RequestContent para chamadas a operações que aceitam parâmetros no corpo da requisição:

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

Há alguns erros restantes para corrigir devido a diferenças entre TanStack Query v4 (usado pelo PDK) e v5 que o gerador connection adicionou:

  1. Substitua isLoading por isPending para mutações, por exemplo:

    putShoppingList.isLoading
    putShoppingList.isPending
  2. A aplicação de lista de compras fez uso do InfiniteQueryTable de @aws-northstar/ui que espera um tipo do TanStack Query v4. Isso na verdade funciona com consultas infinitas do v5, então podemos apenas suprimir o erro de tipo:

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

Agora você pode visitar o website local em http://localhost:4200/

O website deve carregar agora que tudo foi migrado! Como a única infraestrutura de que a aplicação de lista de compras depende além de API, Website e Identity é a tabela DynamoDB - se você tiver uma tabela DynamoDB chamada shopping_list na região, e credenciais AWS locais que possam acessá-la, o website será totalmente funcional!

Se não, tudo bem, vamos migrar a infraestrutura a seguir.

Clique aqui para exemplos completos de antes/depois das duas páginas de lista de compras do tutorial

O último projeto que precisamos migrar para nossa aplicação de lista de compras é o InfrastructureTsProject. Este é um projeto TypeScript CDK, para o qual o equivalente do Nx Plugin for AWS é o gerador ts#infra.

Além dos projetos Projen, o PDK também fornecia constructs CDK dos quais esses projetos dependem. Vamos migrar a aplicação de lista de compras desses constructs CDK também, em favor dos gerados pelo Nx Plugin for AWS.

Execute o gerador ts#infra para configurar seu projeto de infraestrutura em packages/infra:

Terminal window
pnpm nx g @aws/nx-plugin:ts#infra --name=infra --no-interactive
Você também pode realizar uma execução simulada para ver quais arquivos seriam alterados
Terminal window
pnpm nx g @aws/nx-plugin:ts#infra --name=infra --no-interactive --dry-run

A aplicação de lista de compras PDK instanciou os seguintes constructs dentro do stack da aplicação CDK:

  • DatabaseConstruct para a tabela DynamoDB que armazena listas de compras
  • UserIdentity para recursos Cognito, importado diretamente do PDK
  • MyApi para implantar a API Smithy, que usou o construct TypeScript CDK gerado com integrações type-safe, dependendo do construct CDK TypeSafeRestApi do PDK por baixo dos panos.
  • Website para implantar o Website, envolvendo o construct CDK StaticWebsite do PDK.

Em seguida, vamos migrar cada um deles para o novo projeto.

Copie packages/infra/src/stacks/application-stack.ts da aplicação de lista de compras PDK para o exato mesmo local em seu novo projeto. Você verá alguns erros TypeScript que abordaremos abaixo.

A aplicação de lista de compras PDK tinha um construct Database em packages/src/constructs/database.ts. Copie isso para o exato mesmo local em seu novo projeto.

Como o Nx Plugin for AWS usa Checkov para testes de segurança, que é um pouco mais rigoroso que o PDK Nag, também precisamos adicionar algumas supressões:

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',
);

Em application-stack.ts, atualize a importação para o DatabaseConstruct para usar a sintaxe ESM:

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

O construct UserIdentity geralmente pode ser trocado sem alterações ajustando as importações.

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

Note que os constructs subjacentes usados pelo novo construct UserIdentity são fornecidos diretamente de aws-cdk-lib, onde o PDK usava @aws-cdk/aws-cognito-identitypool-alpha.

A aplicação de lista de compras PDK tinha um construct em constructs/apis/myapi.ts que instanciava um construct CDK que o Type Safe API gerou a partir do seu modelo Smithy.

Além deste construct, como o projeto PDK usava o trait @handler, constructs CDK de função lambda gerados também foram gerados.

Como o Type Safe API, o Nx Plugin for AWS fornece type-safety para integrações baseadas no seu modelo Smithy, no entanto, é alcançado de uma maneira muito mais simples e flexível. Em vez de gerar um construct CDK inteiro em tempo de compilação, apenas “metadados” mínimos são gerados, que o packages/common/constructs/src/app/apis/api.ts usa de forma genérica. Você pode aprender mais sobre como usar o construct no guia do gerador ts#smithy-api.

Siga os passos abaixo:

  1. Instancie o construct Api em 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(),
    });

    Note aqui que usamos Api.defaultIntegrations(this).build() - o comportamento padrão é criar uma função lambda para cada operação em nossa API, que é o mesmo comportamento que tínhamos em myapi.ts.

  2. Conceda permissões para as funções lambda acessarem a tabela DynamoDB.

    Na aplicação de lista de compras PDK, o DatabaseConsruct foi passado para MyApi, e ele gerenciava a adição das permissões relevantes a cada construct de função gerado. Faremos isso diretamente no arquivo application-stack.ts acessando a propriedade type-safe integrations do construct 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. Conceda permissões para usuários autenticados invocarem a API.

    Dentro do myapi.ts da aplicação PDK, usuários autenticados também receberam permissões IAM para invocar a API. Faremos o equivalente em application-stack.ts:

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

Finalmente, adicionamos o construct Website de packages/common/constructs/src/app/static-websites/website.ts a application-stack.ts, já que este é o equivalente do packages/infra/src/constructs/websites/website.ts da aplicação 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');

Note que não passamos a identidade ou API para o website - a configuração de runtime é gerenciada dentro de cada construct fornecido pelo Nx Plugin for AWS, onde UserIdentity e Api registram os valores necessários, e Website gerencia a implantação em /runtime-config.json no seu site estático.

Vamos construir o projeto agora que migramos todas as partes relevantes da base de código para nosso novo projeto.

Terminal window
pnpm nx run-many --target build

Agora que temos nossa base de código totalmente migrada, podemos olhar para implantá-la. Existem dois caminhos que podemos seguir neste ponto.

A abordagem mais simples é tratar isso como uma aplicação completamente nova, o que significa que vamos “começar de novo” com uma nova tabela DynamoDB e um novo Cognito User Pool - perdendo todos os usuários e suas listas de compras. Para esta abordagem, simplesmente:

  1. Exclua a tabela DynamoDB chamada shopping_list

  2. Implante a nova aplicação:

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

🎉 E pronto! 🎉

Migrar Recursos com Estado Existentes sem Interrupção (Mais Complexo)

Seção intitulada “Migrar Recursos com Estado Existentes sem Interrupção (Mais Complexo)”

Na realidade, é mais provável que você queira migrar recursos AWS existentes para que sejam gerenciados pela nova base de código, evitando qualquer tempo de inatividade para seus clientes.

Para nossa aplicação de lista de compras, os recursos com estado que nos importam são a tabela DynamoDB que contém as listas de compras de nossos usuários, e o User Pool que contém os detalhes de todos os nossos usuários registrados. Nosso plano de alto nível será reter esses dois recursos-chave e movê-los para que sejam gerenciados por nossa nova pilha, e então atualizar o DNS para apontar para nosso novo site (e API se exposta aos clientes).

  1. Atualize sua nova aplicação para referenciar os recursos existentes que você deseja reter.

    Para a aplicação de lista de compras, fazemos isso para a tabela DynamoDB

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

    E para o 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. Construa e implante a nova aplicação:

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

    Agora temos nossa nova aplicação configurada referenciando os recursos existentes, ainda não recebendo nenhum tráfego.

  3. Execute testes de integração completos para garantir que a nova aplicação funcione conforme esperado. Para a aplicação de lista de compras, carregue o site e verifique se você pode fazer login e criar, visualizar, editar e excluir listas de compras.

  4. Reverta as alterações que referenciam os recursos existentes em sua nova aplicação, mas não as implante ainda.

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

    E para o 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>',
    );

    E então execute uma construção

    Terminal window
    pnpm nx run-many --target build
  5. Use cdk import na pasta packages/infra da sua nova aplicação para ver quais recursos seremos solicitados a importar.

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

    Percorra os prompts pressionando enter. A importação falhará porque os recursos são gerenciados por outra pilha - isso é esperado, fizemos este passo apenas para confirmar quais recursos precisaremos reter. Você verá uma saída como esta:

    Terminal window
    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

    Isso nos diz que na verdade existem 3 recursos que precisaremos importar para nossa nova pilha.

  6. Atualize seu projeto PDK antigo para definir RemovalPolicy como RETAIN para os recursos descobertos no passo anterior. No momento em que este texto foi escrito, este é o padrão tanto para o User Pool quanto para a tabela DynamoDB, mas precisamos atualizá-lo para o SMS Role que descobrimos acima:

    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. Implante seu projeto PDK para que as políticas de remoção sejam aplicadas

    PDK Application
    cd packages/infra
    npx projen deploy
  8. Dê uma olhada no console do CloudFormation e registre os valores para os quais você foi solicitado no passo cdk import acima

    1. O User Pool ID, por exemplo us-west-2_XXXXX
    2. O SMS Role Name, por exemplo infra-sandbox-UserIdentityUserPoolsmsRoleXXXXXX
  9. Atualize seu projeto PDK para referenciar os recursos existentes em vez de criá-los

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

    E para o 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. Implante seu projeto PDK novamente, isso significará que os recursos não são mais gerenciados pela pilha CloudFormation do nosso projeto PDK.

    PDK Application
    cd packages/infra
    npx projen deploy
  11. Agora que os recursos não são gerenciados, podemos executar cdk import em nossa nova aplicação para realmente realizar a importação:

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

    Digite os valores quando solicitado, a importação deve ser concluída com sucesso.

  12. Implante a nova aplicação novamente para garantir que quaisquer alterações nesses recursos existentes (agora gerenciados por sua nova pilha) sejam feitas:

    Terminal window
    pnpm nx deploy infra shopping-list-infra-sandbox/*
  13. Execute um teste completo de sua nova aplicação novamente

  14. Atualize os registros DNS para apontar para seu novo site (e API se necessário).

    Recomendamos uma abordagem gradual usando o Weighted Routing do Route53, pelo qual uma fração das solicitações é direcionada para a nova aplicação no início. À medida que você monitora suas métricas, pode aumentar o peso para a nova aplicação até que nenhum tráfego seja enviado para sua aplicação PDK antiga.

    Se você não tiver nenhum DNS e usou os domínios gerados automaticamente para o site e API, você sempre pode considerar fazer proxy de solicitações (por exemplo, via uma origem HTTP do CloudFront ou integração(ões) HTTP do API Gateway).

  15. Monitore as métricas da aplicação PDK para garantir que não haja tráfego e, finalmente, destrua a pilha CloudFormation antiga:

    Terminal window
    cd packages/infra
    npx projen destroy

Isso foi um pouco mais envolvido, mas migramos nossos usuários perfeitamente para a nova aplicação! 🎉🎉🎉

Agora temos os novos benefícios do Nx Plugin for AWS sobre o PDK:

  • Construções mais rápidas
  • Suporte ao desenvolvimento local de API
  • Uma base de código amigável para vibe-coding (experimente nosso servidor MCP!)
  • Código cliente/servidor type-safe mais intuitivo
  • E muito mais!

Esta seção fornece orientações para recursos do PDK que não são cobertos pelo exemplo de migração acima.

Como regra geral ao migrar do PDK, recomendamos iniciar qualquer projeto com um Nx Workspace, dadas suas semelhanças com o PDK Monorepo. Também recomendamos usar nossos geradores como primitivos sobre os quais construir quaisquer novos tipos.

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

CDK Graph constrói grafos dos seus recursos CDK conectados e fornecia dois plugins:

O CDK Graph Diagram Plugin gera diagramas de arquitetura AWS a partir da sua infraestrutura CDK.

Para uma abordagem determinística similar, uma alternativa viável é CDK-Dia.

Com os avanços em IA Generativa, muitos modelos de fundação são capazes de criar diagramas de alta qualidade a partir da sua infraestrutura CDK. Recomendamos experimentar o AWS Diagram MCP Server. Confira este post do blog para um passo a passo.

O CDK Graph Threat Composer Plugin gera um Threat Composer inicial de modelo de ameaças a partir do seu código CDK.

Este plugin funcionava simplesmente filtrando um modelo de ameaças base contendo exemplos de ameaças, e filtrando-os com base nos recursos que sua stack utilizava.

Se você está interessado nesses exemplos específicos de ameaças, você pode copiar e filtrar o modelo de ameaças base, ou usá-lo como contexto para ajudar um modelo de fundação a gerar um similar.

AWS Arch fornecia mapeamentos entre recursos do CloudFormation e seus ícones de arquitetura associados para o CDK Graph acima.

Consulte a página de Ícones de Arquitetura AWS para recursos relacionados a ícones. Diagrams também fornece uma maneira de construir diagramas como código.

Se você estava usando isso diretamente, considere fazer um fork do projeto e assumir a propriedade!

O PDK fornecia um PDKPipelineProject que configurava um projeto de infraestrutura CDK e fazia uso de um construto CDK que encapsulava alguns recursos de CDK Pipelines.

Para migrar disso, você pode usar os construtos CDK Pipelines diretamente. Na prática, no entanto, é provavelmente mais direto usar algo como GitHub actions ou GitLab CI/CD, onde você define CDK Stages e executa o comando deploy para o estágio apropriado diretamente.

PDK Nag envolve o CDK Nag e fornece um conjunto de regras específicas para construção de protótipos.

Para migrar do PDK Nag, use o CDK Nag diretamente. Se você precisar do mesmo conjunto de regras, pode criar um “pack” próprio seguindo a documentação aqui.

Os componentes mais comumente usados do Type Safe API são cobertos no exemplo de migração acima, no entanto, existem outros recursos, para os quais os detalhes de migração estão abaixo.

O Nx Plugin for AWS suporta APIs modeladas em Smithy, mas não aquelas modeladas diretamente em OpenAPI. O gerador ts#smithy-api é um bom ponto de partida que você pode então modificar. Você pode definir sua especificação OpenAPI na pasta src do projeto model em vez de Smithy, e modificar o build.Dockerfile para usar sua ferramenta de geração de código desejada para clientes/servidores se eles não estiverem disponíveis no NPM. Se suas ferramentas desejadas estiverem no NPM, você pode simplesmente instalá-las como dependências de desenvolvimento no seu workspace Nx e chamá-las diretamente como targets de build do Nx.

Para backends type-safe modelados em OpenAPI, você pode considerar usar um dos OpenAPI Generator Server Generators. Estes não geram diretamente para AWS Lambda, mas você pode usar o AWS Lambda Web Adapter para preencher a lacuna para muitos deles.

Para clientes TypeScript, você pode usar o gerador ts#website e o gerador connection com um exemplo de ts#api (com framework definido como smithy) para ver como os clientes são gerados e integrados com um website. Isso configura targets de build que geram clientes invocando nossos geradores open-api#ts-client ou open-api#ts-hooks. Você pode usar esses geradores você mesmo apontando-os para sua Especificação OpenAPI.

Para outras linguagens, você também pode verificar se algum dos geradores do OpenAPI Generator atende às suas necessidades.

Você também pode construir um gerador personalizado usando o gerador ts#nx-generator. Consulte a documentação desse gerador para detalhes sobre como gerar código a partir de OpenAPI. Você pode usar os templates do Nx Plugin for AWS como ponto de partida. Você também pode até consultar os templates da base de código do PDK para mais inspiração, observando que a estrutura de dados na qual os templates operam é um pouco diferente do Nx Plugin for AWS.

Para TypeSpec, a seção acima para OpenAPI também se aplica. Você pode começar gerando um ts#smithy-api, instalar o compilador TypeSpec e pacotes OpenAPI no seu workspace Nx, e atualizar o target compile do projeto model para executar tsp compile em vez disso, garantindo que ele produza uma especificação OpenAPI no diretório dist.

A abordagem recomendada seria usar o TypeSpec HTTP Server generator for JavaScript para gerar seu código de servidor, já que isso funciona diretamente no seu modelo TypeSpec.

Você pode usar o AWS Lambda Web Adapter para executar o servidor gerado no AWS Lambda.

Você também pode usar qualquer uma das opções OpenAPI acima.

TypeSpec tem seus próprios geradores de código para clientes nas três linguagens suportadas pelo Type Safe API:

A seção OpenAPI acima também se aplica, já que TypeSpec pode compilar para OpenAPI.

O exemplo de migração acima descreve a migração para usar o gerador ts#smithy-api. Esta seção cobre as opções para backends e clientes Python e Java.

O Smithy code generator for Java. Este tem um gerador de servidor Java, bem como um adaptador para executar o servidor Java gerado no AWS Lambda.

Smithy não tem um gerador de servidor para Python, então você precisará passar pelo OpenAPI. Consulte a seção acima sobre APIs Modeladas com OpenAPI para opções potenciais.

O Smithy code generator for Java. Este tem um gerador de cliente Java.

Para clientes Python, você pode conferir Smithy Python.

Para TypeScript, confira Smithy TypeScript, ou use a mesma abordagem que adotamos no ts#smithy-api passando pelo OpenAPI (optamos por isso, pois nos dá consistência entre APIs tRPC, FastAPI e Smithy via hooks TanStack Query).

Type Safe API forneceu um tipo de projeto Projen chamado SmithyShapeLibraryProject que configurava um projeto que continha modelos Smithy que podiam ser reutilizados por múltiplas APIs baseadas em Smithy.

O equivalente é o gerador smithy#project com type definido como shapes:

Terminal window
pnpm nx g @aws/nx-plugin:smithy#project --name=my-shapes --type=shapes
Você também pode realizar uma execução simulada para ver quais arquivos seriam alterados
Terminal window
pnpm nx g @aws/nx-plugin:smithy#project --name=my-shapes --type=shapes --dry-run

Mova as shapes do seu SmithyShapeLibraryProject para a pasta src do projeto gerado, então consulte o guia do projeto Smithy para como conectar a biblioteca como uma dependência do modelo da sua API.

Type Safe API forneceu os seguintes interceptors padrão:

  • Interceptors de logging, tracing e métricas usando Powertools for AWS Lambda
  • Interceptor try-catch para lidar com exceções não capturadas
  • Interceptor CORS para retornar cabeçalhos CORS

O gerador ts#smithy-api instrumenta logging, tracing e métricas com Powertools for AWS Lambda usando Middy. O comportamento do interceptor try-catch está integrado ao Smithy TypeScript SSDK, e os cabeçalhos CORS são adicionados em handler.ts.

Para interceptors de logging, tracing e métricas em qualquer linguagem, use Powertools for AWS Lambda diretamente.

Para migrar interceptors personalizados, recomendamos usar as seguintes bibliotecas:

Type Safe API forneceu geração de documentação usando Redocly CLI. Isso é muito fácil de adicionar a um projeto existente depois de migrá-lo conforme acima.

  1. Instale o Redocly CLI

    Terminal window
    pnpm add -Dw @redocly/cli
  2. Adicione um target de geração de documentação ao seu projeto model usando redocly build-docs, por exemplo:

    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"]
    }
    }

Você também pode considerar os OpenAPI Generator documentation generators.

Type Safe API gerou mocks para você dentro de seu pacote de infraestrutura gerado.

Você pode migrar para JSON Schema Faker que pode criar os dados mock baseados em JSON Schemas. Isso pode funcionar diretamente em uma especificação OpenAPI, e tem uma CLI que você pode executar como parte do build do seu projeto model.

Você pode atualizar sua infraestrutura CDK para ler o arquivo JSON gerado pelo JSON Schema Faker, e retornar a MockIntegration apropriada do API Gateway para uma integração, baseado no metadata.gen.ts gerado (assumindo que você usou o gerador ts#smithy-api).

Type Safe API suportava implementar APIs com uma mistura de diferentes linguagens no backend. Isso também pode ser alcançado fornecendo “overrides” para integrações ao instanciar seu construto de API no 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(),
});

Você precisará criar um “stub” do seu service/router para que seu serviço compile se estiver usando o ts#smithy-api e o TypeScript Server SDK, por exemplo:

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

Type Safe API adicionou validação nativa do API Gateway para corpos de requisição baseada na sua especificação OpenAPI, já que usava o construto SpecRestApi internamente.

Com o gerador ts#smithy-api, a validação é realizada pelo próprio Server SDK. Isso é o mesmo para a maioria dos geradores de servidor.

Se você gostaria de implementar validação nativa do API Gateway, você poderia fazê-lo modificando packages/common/constructs/src/core/api/rest-api.ts para ler o JSON schema relevante para o corpo de requisição de cada operação da sua especificação OpenAPI.

Infelizmente, não há um caminho de migração direto para a API websocket do Type Safe API usando API Gateway e Lambda com desenvolvimento de API orientado a modelo. No entanto, esta seção do guia visa pelo menos oferecer algumas ideias.

Considere usar AsyncAPI para modelar sua API em vez de OpenAPI ou TypeSpec, já que isso é projetado para lidar com APIs assíncronas. O AsyncAPI NodeJS Template pode gerar um backend websocket Node que você poderia hospedar no ECS por exemplo.

Você também pode considerar AppSync Events para infraestrutura, e usar Powertools. Este post do blog vale a pena ler!

Outra opção é usar APIs GraphQL com websockets no AppSync, para o qual temos uma issue no GitHub que você pode dar +1! Consulte o guia do desenvolvedor AppSync para detalhes e links para projetos de exemplo.

Você também pode considerar criar seus próprios geradores de código que interpretam as mesmas extensões de fornecedor que o Type Safe API. Consulte a seção APIs Modeladas com OpenAPI para detalhes sobre como construir geradores personalizados baseados em OpenAPI. Você pode encontrar os templates que o Type Safe API usa para handlers Lambda de API Gateway Websocket API aqui, e o cliente aqui.

Você também pode considerar migrar para usar o gerador ts#trpc-api para usar tRPC. No momento da escrita, ainda não temos suporte para subscriptions/streaming, mas se isso é algo que você precisa, adicione um +1 à nossa issue no GitHub rastreando isso.

Smithy é agnóstico de protocolo, mas ainda não tem suporte para o protocolo Websocket, consulte esta issue no GitHub rastreando o suporte.

O PDK suportava infraestrutura CDK escrita em Python e Java. Não oferecemos suporte para isso no Nx Plugin for AWS no momento da escrita.

O caminho recomendado seria migrar sua infraestrutura CDK para TypeScript, ou usar nossos geradores e migrar o pacote de construtos comuns para a linguagem desejada. Você pode usar IA Generativa para acelerar esse tipo de migração, por exemplo Kiro CLI. Você pode fazer com que um agente de IA itere na migração até que os templates CloudFormation sintetizados sejam idênticos.

O mesmo se aplica à infraestrutura gerada pelo Type Safe API em Python ou Java - você pode traduzir o construto genérico rest-api.ts do pacote de construtos comuns e implementar seu próprio gerador de metadados simples para sua linguagem de destino (consulte a seção APIs Modelled with OpenAPI).

Você pode usar o gerador py#project para um projeto Python base ao qual adicionar seu código CDK (e mover seu arquivo cdk.json, adicionando os targets relevantes). Você pode usar o plugin @nx/gradle do Nx para projetos Java, ou @jnxplus/nx-maven para Maven.

PDK foi construído sobre Projen. Projen e Nx Generators têm diferenças bastante fundamentais, o que significa que, embora seja tecnicamente possível combiná-los, isso provavelmente é um antipadrão. Projen gerencia arquivos de projeto como código de forma que eles não possam ser modificados diretamente, enquanto Nx generators fornecem arquivos de projeto uma vez e então o código pode ser livremente modificado.

Se você deseja continuar a usar Projen, pode implementar os tipos de projeto Projen desejados você mesmo. Para seguir padrões do Nx Plugin for AWS, você pode executar nossos generators ou examinar seu código-fonte no GitHub para ver como os tipos de projeto desejados são construídos e implementar as partes relevantes usando as primitivas do Projen.

Apresentando o Nx Plugin for AWS MCP Server

Em um cenário de desenvolvimento de software em rápida evolução, os assistentes de IA se tornaram colaboradores valiosos em nossa jornada de codificação. Muitos desenvolvedores adotaram o que carinhosamente chamamos de “vibe-coding” - a dança colaborativa entre a criatividade humana e a assistência de IA. Como qualquer prática emergente, ela vem com benefícios empolgantes e desafios notáveis. Este post apresenta o Nx Plugin for AWS MCP Server, que aprimora a experiência de desenvolvimento assistido por IA ao trabalhar com produtos e serviços AWS.

Vibe-coding, a prática de construir software colaborativamente com assistentes de IA, transformou como muitas organizações abordam o desenvolvimento de software. Você descreve o que deseja construir, e seu assistente de IA ajuda a dar vida à sua visão, escrevendo código e testes, executando comandos de build e iterando colaborativamente para completar tarefas grandes e pequenas.

Esta abordagem colaborativa acelerou significativamente os ciclos de desenvolvimento, já que implementações complexas que anteriormente poderiam levar horas para escrever manualmente, muitas vezes podem ser concluídas em minutos.

Apesar de seus benefícios, o vibe-coding vem com armadilhas que podem interromper seu fluxo e levar à frustração. Ferramentas de IA podem produzir padrões inconsistentes em um projeto, o que pode criar dores de cabeça de manutenção no futuro. Sem orientação específica, a IA pode perder práticas recomendadas específicas da AWS ou considerações de segurança importantes que desenvolvedores experientes naturalmente incorporariam.

Sem uma estrutura de projeto clara, o código assistido por IA pode se tornar desorganizado e difícil de manter. A IA pode criar implementações personalizadas para problemas que já têm soluções estabelecidas, reinventando a roda desnecessariamente.

Esses desafios podem levar a dívida técnica, vulnerabilidades de segurança e frustração, especialmente ao trabalhar com vários serviços AWS interconectados e não apenas dentro dos limites de um único framework.

O Nx Plugin for AWS fornece uma base estruturada para construir aplicações AWS usando as ferramentas de monorepo Nx. Em vez de começar com uma tela em branco, o plugin oferece um framework consistente para organização de projetos.

O plugin garante scaffolding de projeto consistente através de geradores para tipos de projeto comuns, o que mantém a integridade estrutural em toda a sua base de código. Ele incorpora templates pré-configurados que seguem as práticas recomendadas da AWS, ajudando desenvolvedores a evitar armadilhas comuns e problemas de segurança. As ferramentas integradas fornecem comandos integrados para construir, testar e implantar aplicações AWS, e simplificar o fluxo de trabalho de desenvolvimento através de servidores de desenvolvimento local. Além disso, ele aproveita o poderoso gerenciamento de dependências do Nx para projetos complexos, simplificando o gerenciamento de monorepo.

Ao fornecer essa estrutura, o Nx Plugin for AWS dá aos assistentes de IA uma estrutura clara para trabalhar. Em vez de inventar padrões do zero, os assistentes de IA podem seguir convenções estabelecidas, levando a uma base de código mais consistente e sustentável.

Model Context Protocol (MCP) é um padrão aberto que permite que assistentes de IA interajam com ferramentas e recursos externos. O Nx Plugin for AWS MCP server estende as capacidades do seu assistente de IA com conhecimento especializado sobre o Nx Plugin for AWS.

O MCP server fornece informações contextuais sobre práticas recomendadas, estruturas de projeto disponíveis e padrões de implementação específicos para o desenvolvimento AWS. Ele permite que suas ferramentas de IA criem workspaces e executem geradores para fazer scaffold de tipos de projeto comuns. Essa consciência contextual ajuda a IA a fazer sugestões mais informadas que se alinham com padrões estabelecidos e evitam armadilhas comuns.

Em vez de produzir código que pode não se alinhar com as práticas recomendadas ou pode referenciar recursos inexistentes, seu assistente de IA pode aproveitar o MCP server para estabelecer uma base para seu projeto. O resultado é uma experiência de desenvolvimento mais determinística e confiável, onde você pode começar com uma base sólida para os componentes principais do seu projeto e usar IA para preencher a lógica de negócios.

Se você está interessado em explorar o desenvolvimento AWS assistido por IA com mais estrutura e confiabilidade, experimente o Nx Plugin for AWS MCP Server. Você pode configurá-lo em seu Assistente de IA favorito (Kiro, Kiro CLI, Cline, Claude Code, etc) com a seguinte configuração do MCP Server:

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

Para instruções detalhadas, consulte nosso guia Construindo com IA.

Bem-vindo ao @aws/nx-plugin

E estamos no ar! 🚀

O Nx Plugin for AWS é um plugin Nx que fornece um conjunto de ferramentas para simplificar o processo de construção e implantação de aplicações full-stack na AWS. Ele fornece aos desenvolvedores modelos pré-configurados para código de aplicação e IaC, reduzindo significativamente o tempo gasto em configuração. O plugin lida com a complexidade da integração de serviços AWS mantendo flexibilidade para personalização.

Os usuários simplesmente escolhem quais componentes desejam da lista de geradores disponíveis, fornecem quaisquer opções de configuração e fazem com que o @aws/nx-plugin gere o código inicial necessário. Vários geradores existem dentro deste conjunto de ferramentas que podem criar APIs, sites, infraestrutura e até fazer coisas mais sofisticadas como integrar um frontend a um backend (incluindo atualização de arquivos existentes via transformações AST!) com clientes type-safe.

generator

Para saber mais, comece com nosso tutorial Dungeon Adventure, que cobre todos os principais componentes do plugin e deve lhe dar uma boa ideia de como usá-lo.

Estamos ansiosos para ouvir seu feedback, não hesite em postar uma discussão ou abrir uma issue para nos dizer o que você pensa e o que gostaria de ver a seguir!

Experimente!