Salta ai contenuti

Jack

3 articoli di Jack

Migrazione da AWS PDK

Questa guida ti accompagna in una migrazione di esempio di un progetto AWS PDK al Plugin Nx per AWS, oltre a fornire indicazioni generali sull’argomento.

La migrazione al Plugin Nx per AWS offre i seguenti vantaggi rispetto a PDK:

  • Build più veloci
  • Facilità d’uso (UI e CLI)
  • Compatibile con il vibe-coding (prova il nostro server MCP!)
  • Tecnologie più moderne
  • Sviluppo locale di API e siti web
  • Maggiore controllo (modifica i file forniti per adattarli al tuo caso d’uso)
  • E altro ancora!

Migrazione di esempio: Applicazione Lista della Spesa

Sezione intitolata “Migrazione di esempio: Applicazione Lista della Spesa”

In questa guida utilizzeremo l’Applicazione Lista della Spesa del Tutorial PDK come progetto target da migrare. Segui i passaggi di quel tutorial per creare il progetto target se vuoi seguire la guida autonomamente.

L’applicazione lista della spesa consiste nei seguenti tipi di progetto PDK:

  • MonorepoTsProject
  • TypeSafeApiProject
  • CloudscapeReactTsWebsiteProject
  • InfrastructureTsProject

Per iniziare, creeremo un nuovo workspace per il nostro nuovo progetto. Sebbene più drastico di una migrazione in-place, questo approccio garantisce il risultato finale più pulito. Creare un workspace Nx è equivalente all’uso di MonorepoTsProject di PDK:

Terminal window
npx create-nx-workspace@21.4.1 shopping-list --pm=pnpm --preset=@aws/nx-plugin@0.50.0 --iacProvider=CDK --ci=skip

Apri la directory shopping-list creata da questo comando nel tuo IDE preferito.

Il TypeSafeApiProject utilizzato nell’applicazione della lista della spesa ha fatto uso di:

  • Smithy come linguaggio di modellazione
  • TypeScript per l’implementazione delle operazioni
  • Generazione di hook TypeScript per l’integrazione con un sito web React

Possiamo quindi utilizzare il generatore ts#smithy-api per fornire funzionalità equivalenti.

Esegui il generatore ts#smithy-api per configurare il tuo progetto API in packages/api:

  1. Installa il Nx Console VSCode Plugin se non l'hai già fatto
  2. Apri la console Nx in VSCode
  3. Clicca su Generate (UI) nella sezione "Common Nx Commands"
  4. Cerca @aws/nx-plugin - ts#smithy-api
  5. Compila i parametri richiesti
    • name: api
    • namespace: com.aws
    • auth: IAM
  6. Clicca su Generate

Noterai che vengono generati un progetto model e un progetto backend. Il progetto model contiene il modello Smithy, mentre backend contiene l’implementazione del server.

Il backend utilizza lo Smithy Server Generator for TypeScript. Esploreremo questo aspetto più avanti.

Ora che abbiamo la struttura base per il nostro progetto API Smithy, possiamo migrare il modello:

  1. Elimina i file Smithy di esempio generati in packages/api/model/src

  2. Copia il tuo modello dalla directory packages/api/model/src/main/smithy del progetto PDK nella directory packages/api/model/src del nuovo progetto.

  3. Aggiorna il nome del servizio e il namespace in smithy-build.json per corrispondere all’applicazione PDK:

    smithy-build.json
    "plugins": {
    "openapi": {
    "service": "com.aws#MyApi",
    ...
  4. Aggiorna il servizio in main.smithy per aggiungere l’errore ValidationException, richiesto quando si utilizza lo 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. Aggiungi un file extensions.smithy in packages/api/model/src dove definiremo un tratto che fornisce informazioni di paginazione al client generato:

    extensions.smithy
    $version: "2"
    namespace com.aws
    use smithy.openapi#specificationExtension
    @trait
    @specificationExtension(as: "x-cursor")
    structure cursor {
    inputToken: String
    enabled: Boolean
    }
  6. Aggiungi il nuovo tratto @cursor all’operazione GetShoppingLists in 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
    }

    Qualsiasi operazione @paginated dovrebbe utilizzare anche @cursor se stai usando il generatore di client fornito dal Nx Plugin for AWS (tramite il generatore api-connection).

  7. Infine, rimuovi il tratto @handler da tutte le operazioni poiché non è supportato dal Nx Plugin for AWS. Utilizzando ts#smithy-api, non abbiamo bisogno dei costrutti CDK per le funzioni lambda auto-generate e dei target di bundling generati da questo tratto, poiché utilizziamo un singolo bundle per tutte le funzioni lambda.

A questo punto, eseguiamo una build per verificare le modifiche al modello e assicurarci di avere del codice server generato con cui lavorare. Ci saranno alcuni errori nel progetto backend (@shopping-list/api) che affronteremo successivamente.

Terminal window
pnpm nx run-many --target build

Puoi considerare il progetto api/backend come equivalente al progetto api/handlers/typescript di Type Safe API.

Una delle principali differenze tra Type Safe API e il generatore ts#smithy-api è che gli handler sono implementati usando lo Smithy Server Generator for TypeScript, anziché i wrapper handler generati da Type Safe API (presenti nel progetto api/generated/typescript/runtime).

Gli handler lambda dell’applicazione lista della spesa fanno affidamento sul pacchetto @aws-sdk/client-dynamodb, quindi installiamolo prima:

Terminal window
pnpm add -w @aws-sdk/client-dynamodb

Poi, copiamo il file handlers/src/dynamo-client.ts dal progetto PDK in backend/src/operations per renderlo disponibile ai nostri handler.

Per migrare gli handler, puoi seguire questi passaggi generali:

  1. Copia l’handler dalla directory packages/api/handlers/typescript/src del progetto PDK nella directory packages/api/backend/src/operations del nuovo progetto.

  2. Rimuovi gli import di my-api-typescript-runtime e importa invece il tipo dell’operazione dallo Smithy Server SDK generato, insieme a ServiceContext per esempio:

    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 l’esportazione del wrapper dell’handler

    export const handler = deleteShoppingListHandler(
    ...INTERCEPTORS,
    deleteShoppingList,
    );
  4. Aggiorna la firma del tuo handler per utilizzare lo SSDK:

    export const deleteShoppingList: DeleteShoppingListChainedHandlerFunction = async (request) => {
    export const DeleteShoppingList: DeleteShoppingListOperation<ServiceContext> = async (input, ctx) => {
  5. Sostituisci l’uso di LoggingInterceptor con ctx.logger. (Si applica anche agli intercettori di metriche e tracing):

    LoggingInterceptor.getLogger(request).info('...');
    ctx.logger.info('...');
  6. Aggiorna i riferimenti ai parametri di input. Poiché lo SSDK fornisce tipi che corrispondono esattamente al tuo modello Smithy (anziché raggruppare separatamente i parametri path/query/header dal parametro body), aggiorna di conseguenza i riferimenti agli input:

    const shoppingListId = request.input.requestParameters.shoppingListId;
    const shoppingListId = input.shoppingListId;
  7. Rimuovi l’uso di Response. Invece restituiamo semplicemente oggetti semplici nello SSDK.

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

    Inoltre, non lanciamo o restituiamo più Response, ma lanciamo gli errori generati dallo 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. Aggiorna gli import per utilizzare la sintassi ESM, aggiungendo l’estensione .js agli import relativi.

  9. Aggiungi l’operazione 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';
    // Registra qui le operazioni per il servizio
    export const Service: MyApiService<ServiceContext> = {
    PutShoppingList,
    GetShoppingLists,
    DeleteShoppingList,
    };
Fai clic qui per gli esempi completi prima/dopo delle tre operazioni della lista della spesa dal tutorial

Abbiamo generato il progetto Smithy API con il nome api inizialmente per posizionarlo in packages/api in coerenza con il progetto PDK. Poiché la nostra API Smithy ora definisce service MyApi invece di service Api, dobbiamo aggiornare tutte le istanze di getApiServiceHandler con getMyApiServiceHandler.

Apporta questa modifica a 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 a 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);

Inoltre, aggiorna packages/api/backend/project.json e modifica metadata.apiName in 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]
},

Ora possiamo eseguire la build del progetto per verificare che la migrazione abbia funzionato finora:

Terminal window
pnpm nx run-many --target build

Il progetto CloudscapeReactTsWebsiteProject utilizzato nell’applicazione della lista della spesa configurava un sito web React con integrazione nativa di CloudScape e autenticazione Cognito.

Questo tipo di progetto si basava su create-react-app, ora deprecato. Per migrare il sito web in questa guida, utilizzeremo il generatore ts#react-website, che impiega tecnologie più moderne e supportate, in particolare Vite.

Come parte della migrazione, passeremo anche dal React Router configurato da PDK a TanStack Router, che aggiunge maggiore type-safety al routing del sito web.

Esegui il generatore ts#react-website per configurare il progetto del sito web in packages/website:

  1. Installa il Nx Console VSCode Plugin se non l'hai già fatto
  2. Apri la console Nx in VSCode
  3. Clicca su Generate (UI) nella sezione "Common Nx Commands"
  4. Cerca @aws/nx-plugin - ts#react-website
  5. Compila i parametri richiesti
    • name: website
  6. Clicca su Generate

Il generatore per siti web React sopra citato non include l’autenticazione Cognito di default come CloudscapeReactTsWebsiteProject, ma può essere aggiunta esplicitamente tramite il generatore ts#react-website#auth.

  1. Installa il Nx Console VSCode Plugin se non l'hai già fatto
  2. Apri la console Nx in VSCode
  3. Clicca su Generate (UI) nella sezione "Common Nx Commands"
  4. Cerca @aws/nx-plugin - ts#react-website#auth
  5. Compila i parametri richiesti
    • project: website
    • cognitoDomain: shopping-list
  6. Clicca su Generate

Questo aggiunge componenti React che gestiscono i redirect necessari per garantire il login degli utenti tramite l’UI ospitata da Cognito. Viene inoltre aggiunto un costrutto CDK per distribuire le risorse Cognito in packages/common/constructs, chiamato UserIdentity.

In PDK era possibile passare i progetti Projen configurati tra loro per attivare l’integrazione. Questo veniva utilizzato nell’applicazione della lista della spesa per configurare l’integrazione tra sito web e API.

Con il Plugin Nx per AWS, l’integrazione API è supportata tramite il generatore api-connection. Utilizziamo ora questo generatore per permettere al nostro sito web di invocare la nostra API Smithy:

  1. Installa il Nx Console VSCode Plugin se non l'hai già fatto
  2. Apri la console Nx in VSCode
  3. Clicca su Generate (UI) nella sezione "Common Nx Commands"
  4. Cerca @aws/nx-plugin - api-connection
  5. Compila i parametri richiesti
    • sourceProject: website
    • targetProject: api
  6. Clicca su Generate

Questo genera i provider client necessari e i target di build affinché il tuo sito web possa chiamare l’API tramite un client TypeScript generato.

Il CloudscapeReactTsWebsiteProject includeva automaticamente una dipendenza da @aws-northstar/ui utilizzata nella nostra applicazione della lista della spesa, quindi la aggiungiamo qui:

Terminal window
pnpm add -w @aws-northstar/ui

L’applicazione della lista della spesa ha un componente chiamato CreateItem e due pagine, ShoppingList e ShoppingLists. Migreremo questi elementi nel nuovo sito web, apportando alcune modifiche per l’utilizzo di TanStack Router e del generatore di client TypeScript del Plugin Nx per AWS.

  1. Copia packages/website/src/components/CreateItem/index.tsx dal progetto PDK nella stessa posizione nel nuovo progetto.

  2. Copia packages/website/src/pages/ShoppingLists/index.tsx in packages/website/src/routes/index.tsx, poiché ShoppingLists è la nostra home page e utilizziamo il routing basato su file con TanStack Router.

  3. Copia packages/website/src/pages/ShoppingList/index.tsx in packages/website/src/routes/$shoppingListId.tsx, poiché ShoppingList è la pagina che vogliamo mostrare sulla rotta /:shoppingListId.

Noterai alcuni errori di compilazione nell’IDE: apporteremo ulteriori modifiche per adattarci al nuovo framework, come descritto di seguito.

Utilizzando il routing basato su file, possiamo usare il server di sviluppo locale per generare automaticamente la configurazione delle rotte. Avviamo il server locale del sito web:

Terminal window
pnpm nx serve-local website

Potresti vedere alcuni errori, ma il server locale del sito web dovrebbe avviarsi sulla porta 4200, e il server Smithy API locale sulla porta 3001.

Segui questi passaggi sia in routes/index.tsx che routes/$shoppingListId.tsx per migrare a TanStack Router:

  1. Aggiungi createFileRoute per registrare ogni rotta:

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

    Dopo il salvataggio, gli errori di tipo su createFileRoute dovrebbero scomparire.

  2. Sostituisci l’hook useNavigate.

    Aggiorna l’import:

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

    Aggiorna le chiamate al metodo navigate per utilizzare le rotte type-safe:

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

    Rimuovi l’import:

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

    Aggiorna le chiamate a useParams con l’hook fornito dalla Route creata:

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

Dato che i file delle rotte non sono più annidati come nel progetto PDK, correggiamo l’import di CreateItem in entrambi i file delle rotte:

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

Anche il contesto AppLayoutContext si trova in una posizione leggermente diversa:

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

Ora migriamo al client TypeScript generato dal Plugin Nx per AWS, che offre diversi miglioramenti rispetto a Type Safe API:

  1. Importa il nuovo client generato invece del vecchio:

    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";
  2. Instanzia i nuovi hook TanStack Query:

    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. Rimuovi i wrapper <operation>RequestContent per le chiamate:

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

Risolvi gli errori rimanenti dovuti alle differenze tra v4 e v5:

  1. Sostituisci isLoading con isPending per le mutazioni:

    putShoppingList.isLoading
    putShoppingList.isPending
  2. Gestisci il tipo per InfiniteQueryTable:

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

Ora puoi visitare il sito web locale all’indirizzo http://localhost:4200/

Il sito dovrebbe caricarsi correttamente dopo la migrazione! L’applicazione richiede solo l’infrastruttura API, Website, Identity e una tabella DynamoDB shopping_list nella stessa regione con credenziali AWS locali valide. Altrimenti, procederemo con la migrazione dell’infrastruttura.

Clicca per vedere gli esempi completi prima/dopo delle due pagine del tutorial

L’ultimo progetto che dobbiamo migrare per la nostra applicazione della lista della spesa è l’InfrastructureTsProject. Si tratta di un progetto TypeScript CDK, per cui l’equivalente nel Plugin Nx per AWS è il generatore ts#infra.

Oltre ai progetti Projen, PDK forniva anche costrutti CDK da cui questi progetti dipendevano. Migreremo l’applicazione della lista della spesa anche da questi costrutti CDK, a favore di quelli generati dal Plugin Nx per AWS.

Genera un Progetto di Infrastruttura TypeScript CDK

Sezione intitolata “Genera un Progetto di Infrastruttura TypeScript CDK”

Esegui il generatore ts#infra per configurare il tuo progetto di infrastruttura in packages/infra:

  1. Installa il Nx Console VSCode Plugin se non l'hai già fatto
  2. Apri la console Nx in VSCode
  3. Clicca su Generate (UI) nella sezione "Common Nx Commands"
  4. Cerca @aws/nx-plugin - ts#infra
  5. Compila i parametri richiesti
    • name: infra
  6. Clicca su Generate

L’applicazione PDK della lista della spesa istanziava i seguenti costrutti all’interno dello stack CDK:

  • DatabaseConstruct per la tabella DynamoDB che memorizza le liste della spesa
  • UserIdentity per le risorse Cognito, importato direttamente da PDK
  • MyApi per distribuire l’API Smithy, che utilizzava il costrutto CDK TypeScript generato con integrazioni type-safe, basato sul costrutto TypeSafeRestApi di PDK.
  • Website per distribuire il sito web, che incapsulava il costrutto StaticWebsite di PDK.

Ora migreremo ciascuno di questi nel nuovo progetto.

Copia packages/infra/src/stacks/application-stack.ts dall’applicazione PDK della lista della spesa nella stessa identica posizione nel tuo nuovo progetto. Vedrai alcuni errori TypeScript che affronteremo di seguito.

L’applicazione PDK aveva un costrutto Database in packages/src/constructs/database.ts. Copialo nella stessa posizione nel nuovo progetto.

Dato che il Plugin Nx per AWS utilizza Checkov per i test di sicurezza, che è leggermente più restrittivo di PDK Nag, dobbiamo aggiungere alcune soppressioni:

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

In application-stack.ts, aggiorna l’import per DatabaseConstruct con la sintassi ESM:

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

Il costrutto UserIdentity può generalmente essere sostituito senza modifiche, aggiornando gli import.

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

Nota che i costrutti sottostanti utilizzati dal nuovo UserIdentity sono forniti direttamente da aws-cdk-lib, mentre PDK utilizzava @aws-cdk/aws-cognito-identitypool-alpha.

L’applicazione PDK aveva un costrutto in constructs/apis/myapi.ts che istanziava un costrutto CDK generato da Type Safe API dal modello Smithy.

Oltre a questo, dato che il progetto PDK utilizzava il trait @handler, venivano generati anche costrutti CDK per le funzioni lambda.

Come Type Safe API, il Plugin Nx per AWS fornisce type-safety per le integrazioni basate sul modello Smithy, ma in modo più semplice e flessibile. Invece di generare un intero costrutto CDK a tempo di build, viene generato solo un minimo “metadata” che il file packages/common/constructs/src/app/apis/api.ts utilizza in modo generico. Puoi saperne di più nell’guida del generatore ts#smithy-api.

Segui questi passaggi:

  1. Istanzia il costrutto Api in 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(),
    });

    Nota qui l’uso di Api.defaultIntegrations(this).build(): il comportamento predefinito è creare una funzione lambda per ogni operazione nella nostra API, come avveniva in myapi.ts.

  2. Concedi i permessi alle funzioni lambda per accedere alla tabella DynamoDB.

    Nell’applicazione PDK, DatabaseConstruct veniva passato a MyApi, che gestiva l’aggiunta dei permessi ai vari costrutti funzione. Ora lo faremo direttamente in application-stack.ts accedendo alla proprietà type-safe integrations del costrutto Api:

    stacks/application-stack.ts
    // Concedi accesso limitato alle lambda per Dynamo
    databaseConstruct.shoppingListTable.grantReadData(
    api.integrations.getShoppingLists.handler,
    );
    [
    api.integrations.putShoppingList.handler,
    api.integrations.deleteShoppingList.handler,
    ].forEach((f) => databaseConstruct.shoppingListTable.grantWriteData(f));
  3. Concedi ai utenti autenticati i permessi per invocare l’API.

    Nell’applicazione PDK, myapi.ts concedeva permessi IAM per invocare l’API. Facciamo l’equivalente in application-stack.ts:

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

Infine, aggiungiamo il costrutto Website da packages/common/constructs/src/app/static-websites/website.ts a application-stack.ts, poiché è l’equivalente del packages/infra/src/constructs/websites/website.ts dell’applicazione PDK.

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

Nota che non passiamo identity o API al website: la configurazione runtime è gestita internamente dai costrutti del Plugin Nx per AWS, dove UserIdentity e Api registrano i valori necessari, e Website li distribuisce in /runtime-config.json sul sito statico.

Ora compiliamo il progetto dopo aver migrato tutte le parti rilevanti.

Terminal window
pnpm nx run-many --target build

Ora che abbiamo la nostra codebase completamente migrata, possiamo procedere con la distribuzione. A questo punto abbiamo due strade percorribili.

L’approccio più semplice è trattare questa come un’applicazione completamente nuova, il che significa che “ricominceremo” con una nuova tabella DynamoDB e un nuovo User Pool Cognito - perdendo tutti gli utenti e le loro liste della spesa. Per questo approccio, basta:

  1. Elimina la tabella DynamoDB denominata shopping_list

  2. Distribuisci la nuova applicazione:

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

🎉 E abbiamo finito! 🎉

Migrare le Risorse Esistenti con Stato Senza Interruzioni (Più Complesso)

Sezione intitolata “Migrare le Risorse Esistenti con Stato Senza Interruzioni (Più Complesso)”

Nella realtà, è più probabile che tu voglia migrare le risorse AWS esistenti in modo che siano gestite dalla nuova codebase, evitando nel contempo qualsiasi interruzione del servizio per i clienti.

Per la nostra applicazione delle liste della spesa, le risorse con stato che ci interessano sono la tabella DynamoDB che contiene le liste della spesa degli utenti e l’User Pool che contiene i dettagli di tutti gli utenti registrati. Il nostro piano ad alto livello sarà mantenere queste due risorse chiave e spostarle in modo che siano gestite dal nuovo stack, per poi aggiornare il DNS per puntare al nuovo sito web (e all’API se esposta ai clienti).

  1. Aggiorna la nuova applicazione per riferirsi alle risorse esistenti che desideri mantenere.

    Per l’applicazione delle liste della spesa, facciamo questo per la tabella DynamoDB

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

    E per l’User Pool Cognito

    packages/common/constructs/src/core/user-identity.ts
    this.userPool = this.createUserPool();
    this.userPool = UserPool.fromUserPoolId(
    this,
    'UserPool',
    '<your-user-pool-id>',
    );
  2. Compila e distribuisci la nuova applicazione:

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

    Ora abbiamo la nuova applicazione attiva che fa riferimento alle risorse esistenti, ma non ancora in produzione.

  3. Esegui test di integrazione completi per verificare che la nuova applicazione funzioni come previsto. Per l’applicazione delle liste della spesa, carica il sito web e verifica di poter accedere, creare, visualizzare, modificare ed eliminare liste.

  4. Ripristina le modifiche che fanno riferimento alle risorse esistenti nella nuova applicazione, ma non distribuirle ancora.

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

    E per l’User Pool Cognito

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

    E poi esegui una compilazione

    Terminal window
    pnpm nx run-many --target build
  5. Usa cdk import nella cartella packages/infra della nuova applicazione per vedere quali risorse verranno proposte per l’importazione.

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

    Procedi attraverso le richieste premendo invio. L’importazione fallirà perché le risorse sono gestite da un altro stack - è previsto, abbiamo fatto questo passaggio solo per confermare quali risorse dovremo mantenere. Vedrai un output simile a questo:

    Terminal window
    shopping-list-infra-sandbox/Application/ApplicationUserIdentity/UserPool/smsRole/Resource (AWS::IAM::Role): inserisci RoleName (vuoto per saltare)
    shopping-list-infra-sandbox/Application/ApplicationUserIdentity/UserPool/Resource (AWS::Cognito::UserPool): inserisci UserPoolId (vuoto per saltare)
    shopping-list-infra-sandbox/Application/Database/ShoppingList/Resource (AWS::DynamoDB::Table): importa con TableName=shopping_list (y/n) y

    Questo ci dice che in realtà ci sono 3 risorse da importare nel nuovo stack.

  6. Aggiorna il tuo vecchio progetto PDK per impostare RemovalPolicy su RETAIN per le risorse individuate nel passaggio precedente. Al momento della stesura questa è l’impostazione predefinita sia per l’User Pool che per la tabella DynamoDB, ma dobbiamo aggiornarla per il ruolo SMS individuato sopra:

    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. Distribuisci il progetto PDK per applicare le politiche di rimozione

    Applicazione PDK
    cd packages/infra
    npx projen deploy
  8. Controlla la console CloudFormation e registra i valori richiesti nel passaggio cdk import precedente

    1. L’ID dell’User Pool, es. us-west-2_XXXXX
    2. Il nome del ruolo SMS, es. infra-sandbox-UserIdentityUserPoolsmsRoleXXXXXX
  9. Aggiorna il progetto PDK per riferirsi alle risorse esistenti invece di crearne di nuove

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

    E per l’User Pool Cognito

    application-stack.ts
    const userPool = UserPool.fromUserPoolId(
    this,
    'UserPool',
    '<your-user-pool-id>',
    );
    const userIdentity = new UserIdentity(this, `${id}UserIdentity`, {
    // Il costrutto PDK accetta UserPool non IUserPool, ma funziona comunque!
    userPool: userPool as any,
    });
  10. Distribuisci nuovamente il progetto PDK, questo significa che le risorse non saranno più gestite dallo stack CloudFormation del progetto PDK.

    Applicazione PDK
    cd packages/infra
    npx projen deploy
  11. Ora che le risorse non sono gestite, possiamo eseguire cdk import nella nuova applicazione per completare l’importazione:

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

    Inserisci i valori quando richiesto, l’importazione dovrebbe completarsi con successo.

  12. Distribuisci nuovamente la nuova applicazione per assicurarti che eventuali modifiche a queste risorse esistenti (ora gestite dal nuovo stack) vengano applicate:

    Terminal window
    pnpm nx deploy infra shopping-list-infra-sandbox/*
  13. Esegui nuovamente un test completo della nuova applicazione

  14. Aggiorna i record DNS per puntare al nuovo sito web (e all’API se necessario).

    Raccomandiamo un approccio graduale usando il Routing Ponderato di Route53, dove inizialmente una frazione delle richieste viene indirizzata alla nuova applicazione. Monitorando le metriche, puoi aumentare gradualmente il peso per la nuova applicazione finché tutto il traffico non viene indirizzato lì.

    Se non hai DNS e hai usato i domini auto-generati per sito web e API, puoi considerare il proxy delle richieste (es. tramite un origine HTTP CloudFront o integrazioni HTTP API Gateway).

  15. Monitora le metriche dell’applicazione PDK per assicurarti che non ci sia traffico residuo, infine elimina il vecchio stack CloudFormation:

    Terminal window
    cd packages/infra
    npx projen destroy

È stato piuttosto articolato, ma abbiamo migrato gli utenti in modo trasparente alla nuova applicazione! 🎉🎉🎉

Ora abbiamo i nuovi vantaggi di Nx Plugin for AWS rispetto a PDK:

  • Build più veloci
  • Supporto allo sviluppo locale delle API
  • Una codebase amichevole per il vibe-coding (prova il nostro server MCP!)
  • Codice client/server type-safe più intuitivo
  • E altro ancora!

Questa sezione fornisce indicazioni per funzionalità di PDK non coperte dall’esempio di migrazione sopra.

Come regola generale quando si passa da PDK, consigliamo di iniziare qualsiasi progetto con un Workspace Nx, date le sue somiglianze con il Monorepo PDK. Consigliamo inoltre di utilizzare i nostri generatori come primitive su cui costruire nuovi tipi.

Terminal window
npx create-nx-workspace@21.4.1 my-project --pm=pnpm --preset=@aws/nx-plugin --ci=skip

CDK Graph costruisce grafici delle tue risorse CDK connesse e fornisce due plugin:

Il CDK Graph Diagram Plugin genera diagrammi dell’architettura AWS dalla tua infrastruttura CDK.

Un’alternativa valida con approccio deterministico simile è CDK-Dia.

Con i progressi nell’AI generativa, molti modelli di base sono in grado di creare diagrammi di alta qualità dalla tua infrastruttura CDK. Consigliamo di provare AWS Diagram MCP Server. Consulta questo blog post per una guida passo passo.

Il CDK Graph Threat Composer Plugin genera un modello di minaccia iniziale per Threat Composer dal tuo codice CDK.

Questo plugin funziona semplicemente filtrando un modello di minaccia base contenente minacce di esempio, selezionando quelle rilevanti in base alle risorse utilizzate dal tuo stack.

Se sei interessato a queste minacce di esempio specifiche, puoi copiare e filtrare il modello base, o usarlo come contesto per far generare un modello simile da un modello di AI generativa.

AWS Arch forniva le mappature tra le risorse di CloudFormation e le relative icone architetturali associate per CDK Graph sopra menzionato.

Fai riferimento alla pagina delle icone architetturali AWS per le risorse relative alle icone. Diagrams fornisce anche un modo per creare diagrammi come codice.

Se stavi utilizzando direttamente questo progetto, valuta di effettuare un fork del progetto e prendertene carico!

Il PDK forniva un PDKPipelineProject che configurava un progetto di infrastruttura CDK e utilizzava un costrutto CDK che incapsulava alcune risorse delle CDK Pipelines.

Per migrare da questo approccio, puoi utilizzare direttamente i costrutti delle CDK Pipelines. Tuttavia, nella pratica è spesso più semplice utilizzare soluzioni come GitHub Actions o GitLab CI/CD, dove si definiscono CDK Stages e si esegue direttamente il comando di deploy per lo stage appropriato.

PDK Nag incapsula CDK Nag e fornisce una serie di regole specifiche per la creazione di prototipi.

Per migrare da PDK Nag, utilizza direttamente CDK Nag. Se hai bisogno dello stesso set di regole, puoi creare un tuo “pack” personale seguendo la documentazione qui disponibile.

I componenti più comunemente utilizzati da Type Safe API sono coperti nell’esempio di migrazione sopra riportato, tuttavia esistono altre funzionalità per cui i dettagli di migrazione sono descritti di seguito.

L’Nx Plugin per AWS supporta API modellate in Smithy, ma non quelle modellate direttamente in OpenAPI. Il generatore ts#smithy-api è un buon punto di partenza che puoi poi modificare. Puoi definire la tua specifica OpenAPI nella cartella src del progetto model invece di Smithy, e modificare il build.Dockerfile per utilizzare il tuo strumento di generazione codice preferito per client/server se non disponibile su NPM. Se gli strumenti desiderati sono su NPM, puoi semplicemente installarli come dipendenze dev nel tuo workspace Nx e richiamarli direttamente come target di build Nx.

Per backend type-safe modellati in OpenAPI, puoi considerare l’uso di uno dei Server Generator di OpenAPI Generator. Questi non generano codice direttamente per AWS Lambda, ma puoi utilizzare AWS Lambda Web Adapter come ponte per molti di essi.

Per client TypeScript, puoi utilizzare i generatori ts#react-website e api-connection con un esempio ts#smithy-api per vedere come i client vengono generati e integrati con un sito web. Questo configura target di build che generano client invocando i nostri generatori open-api#ts-client o open-api#ts-hooks. Puoi usare questi generatori puntandoli alla tua specifica OpenAPI.

Per altri linguaggi, puoi verificare se alcuni dei Client Generator di OpenAPI Generator soddisfano le tue esigenze.

Puoi anche costruire un generatore personalizzato utilizzando il generatore ts#nx-generator. Consulta la documentazione di quel generatore per dettagli su come generare codice da OpenAPI. Puoi usare i template dell’Nx Plugin per AWS come punto di partenza. Puoi anche ispirarti ai template del codice PDK, notando che la struttura dati su cui operano i template è leggermente diversa rispetto all’Nx Plugin per AWS.

Per TypeSpec, vale quanto riportato nella sezione precedente su OpenAPI. Puoi iniziare generando un ts#smithy-api, installare il compilatore TypeSpec e i pacchetti OpenAPI nel tuo workspace Nx, e aggiornare il target compile del progetto model per eseguire tsp compile invece, assicurandoti che produca una specifica OpenAPI nella cartella dist.

L’approccio raccomandato è utilizzare il TypeSpec HTTP Server generator per JavaScript per generare il codice server, poiché opera direttamente sul modello TypeSpec.

Puoi usare AWS Lambda Web Adapter per eseguire il server generato su AWS Lambda.

Puoi anche utilizzare una qualsiasi delle opzioni OpenAPI sopra menzionate.

TypeSpec ha i suoi generatori di codice per client in tutti e tre i linguaggi supportati da Type Safe API:

La sezione OpenAPI sopra riportata si applica anche qui poiché TypeSpec può compilare in OpenAPI.

L’esempio di migrazione sopra descritto illustra la migrazione all’uso del generatore ts#smithy-api. Questa sezione copre le opzioni per backend e client in Python e Java.

Il generatore Smithy per Java. Questo include un generatore di server Java e un adapter per eseguire il server Java generato su AWS Lambda.

Smithy non ha un generatore di server per Python, quindi dovrai passare attraverso OpenAPI. Fai riferimento alla sezione precedente sulle API Modellate con OpenAPI per opzioni possibili.

Il generatore Smithy per Java. Questo include un generatore di client Java.

Per client Python, puoi consultare Smithy Python.

Per TypeScript, consulta Smithy TypeScript, o usa lo stesso approccio adottato in ts#smithy-api passando attraverso OpenAPI (abbiamo optato per questa soluzione per garantire coerenza tra API tRPC, FastAPI e Smithy tramite hook TanStack Query).

Type Safe API forniva un tipo di progetto Projen chiamato SmithyShapeLibraryProject che configurava un progetto contenente modelli Smithy riutilizzabili da più API basate su Smithy.

Il modo più diretto per ottenere ciò è il seguente:

  1. Crea la tua shape library usando il generatore smithy#project:

    1. Installa il Nx Console VSCode Plugin se non l'hai già fatto
    2. Apri la console Nx in VSCode
    3. Clicca su Generate (UI) nella sezione "Common Nx Commands"
    4. Cerca @aws/nx-plugin - smithy#project
    5. Compila i parametri richiesti
      • Clicca su Generate

      Specifica un nome qualsiasi per l’opzione serviceName, poiché rimuoveremo la shape service.

    6. Sostituisci il modello predefinito in src con le shape che desideri definire

    7. Aggiorna smithy-build.json rimuovendo i plugins e le dipendenze Maven non utilizzate

    8. Sostituisci build.Dockerfile con passaggi di build minimi:

      build.Dockerfile
      FROM public.ecr.aws/docker/library/node:24 AS builder
      # Directory di output
      RUN mkdir /out
      # Installa Smithy CLI
      # https://smithy.io/2.0/guides/smithy-cli/cli_installation.html
      WORKDIR /smithy
      ARG TARGETPLATFORM
      RUN if [ "$TARGETPLATFORM" = "linux/arm64" ]; then ARCH="aarch64"; else ARCH="x86_64"; fi && \
      mkdir -p smithy-install/smithy && \
      curl -L https://github.com/smithy-lang/smithy/releases/download/1.61.0/smithy-cli-linux-$ARCH.zip -o smithy-install/smithy-cli-linux-$ARCH.zip && \
      unzip -qo smithy-install/smithy-cli-linux-$ARCH.zip -d smithy-install && \
      mv smithy-install/smithy-cli-linux-$ARCH/* smithy-install/smithy
      RUN smithy-install/smithy/install
      # Copia i file del progetto
      COPY smithy-build.json .
      COPY src src
      # Build Smithy con cache Maven
      RUN --mount=type=cache,target=/root/.m2/repository,id=maven-cache \
      smithy build
      RUN cp -r build/* /out/
      # Esporta la directory /out
      FROM scratch AS export
      COPY --from=builder /out /

    Nei tuoi progetti di modello di servizio, apporta le seguenti modifiche per utilizzare la shape library:

    1. Aggiorna il target compile in project.json per aggiungere il workspace come contesto di build e una dipendenza sul target build della shape library

      project.json
      {
      "cache": true,
      "outputs": ["{workspaceRoot}/dist/{projectRoot}/build"],
      "executor": "nx:run-commands",
      "options": {
      "commands": [
      "rimraf dist/packages/api/model/build",
      "make-dir dist/packages/api/model/build",
      "docker build --build-context workspace=. -f packages/api/model/build.Dockerfile --target export --output type=local,dest=dist/packages/api/model/build packages/api/model"
      ],
      "parallel": false,
      "cwd": "{workspaceRoot}"
      },
      "dependsOn": ["@my-project/shapes:build"]
      }
    2. Aggiorna build.Dockerfile per copiare la directory src dalla tua shape library. Ad esempio, assumendo che la shape library sia in packages/shapes:

      build.Dockerfile
      # Copia i file del progetto
      COPY smithy-build.json .
      COPY src src
      COPY --from=workspace packages/shapes/src shapes
    3. Aggiorna smithy-build.json per aggiungere la directory shapes alle sue sources:

      smithy-build.json
      {
      "version": "1.0",
      "sources": ["src/", "shapes/"],
      "plugins": {
      ...
      }

    Type Safe API forniva i seguenti interceptors predefiniti:

    • Interceptors di logging, tracing e metriche utilizzando Powertools for AWS Lambda
    • Interceptor try-catch per gestire eccezioni non catturate
    • Interceptor CORS per restituire header CORS

    Il generatore ts#smithy-api strumenta logging, tracing e metriche con Powertools for AWS Lambda usando Middy. Il comportamento dell’interceptor try-catch è integrato nello Smithy TypeScript SSDK, e gli header CORS vengono aggiunti in handler.ts.

    Per interceptors di logging, tracing e metriche in qualsiasi linguaggio, usa direttamente Powertools for AWS Lambda.

    Per migrare interceptors personalizzati, raccomandiamo l’uso delle seguenti librerie:

    Type Safe API forniva generazione di documentazione usando Redocly CLI. Questo è facilmente aggiungibile a un progetto esistente dopo la migrazione.

    1. Installa Redocly CLI

      Terminal window
      pnpm add -Dw @redocly/cli
    2. Aggiungi un target di generazione documentazione al tuo progetto model usando redocly build-docs, ad esempio:

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

    Puoi anche considerare i documentation generator di OpenAPI Generator.

    Type Safe API generava mock per te all’interno del suo pacchetto infrastrutturale.

    Puoi passare a JSON Schema Faker che può creare dati mock basati su JSON Schema. Questo può lavorare direttamente su una specifica OpenAPI, e ha una CLI che puoi eseguire come parte della build del progetto model.

    Puoi aggiornare la tua infrastruttura CDK per leggere il file JSON generato da JSON Schema Faker, e restituire l’appropriata MockIntegration di API Gateway per un’integrazione, basata su metadata.gen.ts (assumendo che tu abbia usato il generatore ts#smithy-api).

    Type Safe API supportava l’implementazione di API con un mix di linguaggi nel backend. Questo può essere ottenuto fornendo “override” alle integrazioni quando istanzi il tuo costrutto API in 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(),
    });

    Dovrai “stubare” il tuo service/router per far compilare il servizio se usi ts#smithy-api e l’SDK Server TypeScript, ad esempio:

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

    Type Safe API aggiungeva validazione nativa di API Gateway per i corpi delle richieste basata sulla tua specifica OpenAPI, poiché utilizzava il costrutto SpecRestApi.

    Con il generatore ts#smithy-api, la validazione è eseguita dall’SDK Server stesso. Questo vale per la maggior parte dei generatori di server.

    Se desideri implementare la validazione nativa di API Gateway, puoi farlo modificando packages/common/constructs/src/core/api/rest-api.ts per leggere lo schema JSON rilevante per il corpo della richiesta di ogni operazione dalla tua specifica OpenAPI.

    Purtroppo non esiste un percorso di migrazione diretto per le API websocket di Type Safe API che utilizzano API Gateway e Lambda con sviluppo API guidato da modelli. Tuttavia, questa sezione della guida mira almeno a offrire qualche idea.

    Considera l’uso di AsyncAPI per modellare la tua API invece di OpenAPI o TypeSpec, poiché è progettato per gestire API asincrone. Il Template NodeJS di AsyncAPI può generare un backend websocket Node che puoi ospitare su ECS, ad esempio.

    Puoi anche considerare AppSync Events per l’infrastruttura, e usare Powertools. Questo blog post è una lettura consigliata!

    Un’altra opzione è usare API GraphQL con websocket su AppSync, per cui abbiamo un GitHub issue su cui puoi votare! Consulta la guida per sviluppatori di AppSync per dettagli e link a progetti di esempio.

    Puoi anche considerare lo sviluppo di generatori di codice personalizzati che interpretino le stesse estensioni vendor di Type Safe API. Fai riferimento alla sezione API Modellate con OpenAPI per dettagli sulla creazione di generatori di codice basati su OpenAPI. Puoi trovare i template che Type Safe API utilizza per gli handler Lambda di API Gateway Websocket qui, e il client qui.

    Puoi anche considerare la migrazione al generatore ts#trpc-api per usare tRPC. Al momento non supportiamo ancora sottoscrizioni/streaming, ma se ne hai bisogno aggiungi un +1 al nostro GitHub issue.

    Smithy è agnostico rispetto al protocollo, ma non supporta ancora il protocollo Websocket, fai riferimento a questo GitHub issue.

    PDK supporta infrastrutture CDK scritte in Python e Java. Al momento della stesura di questo documento, non forniamo supporto per questo nel Plugin Nx per AWS.

    La soluzione consigliata è migrare la tua infrastruttura CDK a TypeScript oppure utilizzare i nostri generatori e migrare il pacchetto di costrutti comuni al linguaggio desiderato. Puoi utilizzare l’Intelligenza Artificiale Generativa per accelerare questo tipo di migrazioni, ad esempio Amazon Q CLI. Un agente IA può iterare sulla migrazione finché i modelli CloudFormation sintetizzati non risultano identici.

    Lo stesso vale per l’infrastruttura generata da Type Safe API in Python o Java: puoi tradurre il costrutto generico rest-api.ts dal pacchetto comune e implementare il tuo generatore di metadati semplificato per il linguaggio target (fai riferimento alla sezione API Modellate con OpenAPI).

    Puoi utilizzare il generatore py#project come base per progetti Python a cui aggiungere il tuo codice CDK (spostando il file cdk.json e aggiungendo target rilevanti). Per progetti Java, puoi usare il plugin @nx/gradle di Nx oppure @jnxplus/nx-maven per Maven.

    Il PDK è stato costruito su Projen. Projen e gli Nx Generators presentano differenze piuttosto fondamentali, pertanto sebbene tecnicamente sia possibile combinarli, ciò rappresenta probabilmente un anti-pattern. Projen gestisce i file di progetto come codice in modo che non possano essere modificati direttamente, mentre i generatori Nx forniscono i file di progetto una volta e successivamente il codice può essere liberamente modificato.

    Se desideri continuare a utilizzare Projen, puoi implementare autonomamente i tipi di progetto Projen che ti interessano. Per seguire gli schemi del Plugin Nx per AWS, puoi eseguire i nostri generatori o esaminare il loro codice sorgente su GitHub per comprendere come sono costruiti i tipi di progetto desiderati, quindi implementare le parti rilevanti utilizzando i primitivi di Projen.

    Introduzione del Plugin Nx per AWS MCP Server

    In un panorama in rapida evoluzione dello sviluppo software, gli assistenti AI sono diventati collaboratori preziosi nel nostro percorso di codifica. Molti sviluppatori hanno abbracciato ciò che chiamiamo affettuosamente “vibe-coding” - la danza collaborativa tra creatività umana e assistenza AI. Come qualsiasi pratica emergente, presenta sia vantaggi entusiasmanti che sfide significative. Questo post introduce il Nx Plugin per AWS MCP Server, che migliora l’esperienza di sviluppo assistito da AI quando si lavora con prodotti e servizi AWS.

    Il vibe-coding, la pratica di costruire software in modo collaborativo con assistenti AI, ha trasformato il modo in cui molte organizzazioni affrontano lo sviluppo software. Descrivete ciò che volete costruire e il vostro assistente AI aiuta a realizzare la vostra visione, scrivendo codice e test, eseguendo comandi di build e iterando in modo collaborativo per completare attività sia grandi che piccole.

    Questo approccio collaborativo ha accelerato significativamente i cicli di sviluppo, poiché implementazioni complesse che in precedenza richiedevano ore di scrittura manuale possono spesso essere completate in pochi minuti.

    Nonostante i suoi vantaggi, il vibe-coding presenta insidie che possono interrompere il flusso di lavoro e portare a frustrazione. Gli strumenti AI possono produrre pattern incoerenti all’interno di un progetto, creando problemi di manutenzione a lungo termine. Senza linee guida specifiche, l’AI potrebbe trascurare best practice specifiche di AWS o considerazioni sulla sicurezza che sviluppatori esperti incorporerebbero naturalmente.

    Senza una struttura di progetto chiara, il codice generato con assistenza AI può diventare disorganizzato e difficile da mantenere. L’AI potrebbe creare implementazioni personalizzate per problemi che hanno già soluzioni consolidate, reinventando inutilmente la ruota.

    Queste sfide possono portare a debito tecnico, vulnerabilità di sicurezza e frustrazione, specialmente quando si lavora con vari servizi AWS interconnessi e non solo all’interno dei confini di un singolo framework.

    Il Nx Plugin per AWS fornisce una base strutturata per costruire applicazioni AWS utilizzando gli strumenti monorepo di Nx. Invece di partire da una tela vuota, il plugin offre un framework coerente per l’organizzazione dei progetti.

    Il plugin garantisce un’impalcatura di progetto coerente attraverso generatori per tipi di progetto comuni, mantenendo l’integrità strutturale del codebase. Incorpora template preconfigurati che seguono le best practice AWS, aiutando gli sviluppatori a evitare insidie comuni e problemi di sicurezza. Gli strumenti integrati forniscono comandi built-in per build, test e deploy di applicazioni AWS, semplificando il flusso di lavoro di sviluppo attraverso server di sviluppo locali. Inoltre, sfrutta la potente gestione delle dipendenze di Nx per progetti complessi, semplificando la gestione del monorepo.

    Fornendo questa struttura, il Nx Plugin per AWS dà agli assistenti AI un framework chiaro in cui operare. Invece di inventare pattern da zero, gli assistenti AI possono seguire convenzioni stabilite, portando a un codebase più coerente e mantenibile.

    Il Model Context Protocol (MCP) è uno standard aperto che permette agli assistenti AI di interagire con strumenti e risorse esterne. Il server MCP del Nx Plugin per AWS estende le capacità del vostro assistente AI con conoscenze specializzate sul Nx Plugin per AWS.

    Il server MCP fornisce informazioni contestuali su best practice, strutture di progetto disponibili e pattern di implementazione specifici per lo sviluppo AWS. Abilita i vostri strumenti AI a creare workspace ed eseguire generatori per scaffoldare tipi di progetto comuni. Questa consapevolezza contestuale aiuta l’AI a fare suggerimenti più informati, allineati con pattern consolidati ed evitando insidie comuni.

    Invece di produrre codice che potrebbe non allinearsi alle best practice o riferire funzionalità inesistenti, il vostro assistente AI può sfruttare il server MCP per gettare le basi del progetto. Il risultato è un’esperienza di sviluppo più deterministica e affidabile, dove potete iniziare con una solida base per i componenti core del progetto e usare l’AI per implementare la logica di business.

    Se siete interessati a esplorare lo sviluppo AWS assistito da AI con più struttura e affidabilità, provate il Nx Plugin per AWS MCP Server. Potete configurarlo nel vostro assistente AI preferito (Amazon Q Developer, Cline, Claude Code, ecc.) con la seguente configurazione del server MCP:

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

    Per istruzioni dettagliate, consultate la nostra guida Building with AI.

    Benvenuti in @aws/nx-plugin

    Eee siamo online! 🚀

    Il Plugin Nx per AWS è un plugin Nx che fornisce un kit di strumenti per semplificare la creazione e il deployment di applicazioni full-stack su AWS. Offre agli sviluppatori modelli preconfigurati per codice applicativo e infrastrutturale (IaC), riducendo significativamente il tempo dedicato alla configurazione iniziale. Il plugin gestisce la complessità dell’integrazione con i servizi AWS mantenendo la flessibilità per personalizzazioni.

    Gli utenti possono semplicemente selezionare i componenti desiderati dalla lista di generatori disponibili, fornire le opzioni di configurazione e far generare a @aws/nx-plugin il codice iniziale richiesto. La toolkit include diversi generatori per creare API, siti web, infrastrutture, e persino operazioni più avanzate come l’integrazione di frontend e backend (con aggiornamenti automatici dei file esistenti tramite trasformazioni AST!) con client type-safe.

    generator

    Per approfondire, inizia con il nostro tutorial Dungeon Adventure, che copre tutti i componenti principali del plugin e ti darà un’idea chiara del suo utilizzo.

    Siamo ansiosi di ricevere il tuo feedback! Non esitare a aprire una discussione o segnalare un problema per farci sapere cosa ne pensi e cosa vorresti vedere in futuro.

    Provalo subito!