Costruire un’applicazione web completa con i servizi di AWS

Creare un'app web completa con AWS

Introduzione

Quando iniziamo a imparare AWS, di solito impariamo pezzi di esso, come alcuni dei servizi principali; lavorando sulla console AWS, potremmo creare una nuova istanza EC2 o un bucket S3 e caricarvi qualcosa. Ma nella maggior parte dei casi, non riuscivamo a mettere insieme tutti i servizi in un’applicazione reale. Conosciamo diversi servizi AWS che abbiamo imparato ma non siamo in grado di metterli insieme in qualcosa di effettivamente utilizzabile, e se ti senti allo stesso modo, sei nel posto giusto. Dopo aver terminato questo articolo, sarai in grado di costruire un’applicazione di gestione delle password ospitata su AWS, che esegue i suoi calcoli nel server AWS, i dati dell’utente verranno inviati al server backend tramite un API Gateway, il risultato finale verrà mostrato all’utente nel browser e i dati verranno anche archiviati in un database AWS.

Assicurati di avere un account AWS e l’accesso alla console prima di procedere. La conoscenza precedente di AWS non è necessaria per questo articolo; se hai già una comprensione di base, ti sarà utile, se non lo sai, dovresti comunque essere in grado di seguirci mentre costruiamo la nostra applicazione. Questo articolo non è destinato ad approfondire nessuno dei servizi AWS, ma è destinato a metterli tutti insieme in un’applicazione funzionante.

Obiettivi di apprendimento

  • Crea un’applicazione web end-to-end integrando diversi servizi AWS.
  • Impara come distribuire e ospitare applicazioni web utilizzando AWS Amplify.
  • Impara come creare un server backend utilizzando AWS Lambda.
  • Impara come utilizzare API Gateway per il trasferimento di dati tra i componenti frontend e backend.
  • Impara come archiviare e recuperare dati dal database AWS DynamoDB.

Panoramica dei servizi e dell’applicazione che costruiremo

Questo articolo utilizza cinque servizi AWS per costruire applicazioni web end-to-end da zero, come mostrato nell’immagine sopra. Creeremo un’applicazione di gestione delle password sicura che genera e archivia password sicure inserendo il nome, la lunghezza e le proprietà delle password (lettere maiuscole, lettere minuscole, numeri, caratteri speciali). Si tratta di un’applicazione semplice, ma mette insieme tutti i principali componenti necessari per costruire un’applicazione del mondo reale molto più grande.

Cosa dobbiamo fare per costruire questa applicazione?

1.      Dobbiamo creare e ospitare una pagina web a cui i nostri utenti accederanno dai loro browser.

2.     Abbiamo bisogno di un modo per invocare la funzionalità di generazione delle password.

3.     Abbiamo bisogno di un modo per eseguire i calcoli che restituiscono i risultati.

4.      Abbiamo bisogno di un modo per archiviare il risultato e abbiamo bisogno di un modo per restituire il risultato all’utente.

5.      Dobbiamo gestire i permessi di questi servizi in AWS.

Creazione e distribuzione di una pagina web live utilizzando AWS Amplify

In AWS, ci sono effettivamente diversi modi per farlo. Sceglieremo AWS Amplify; con Amplify, possiamo creare e ospitare siti web. È un ottimo servizio, soprattutto se sei uno sviluppatore frontend. Creeremo una pagina HTML e poi utilizzeremo Amplify per distribuire e ospitare quella pagina web. Facciamolo adesso. Di seguito è riportato un semplice codice HTML che visualizza il nome del nostro articolo quando lo apriamo.

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title> Gestore di password sicure! </title>
</head>
<body>
    Creazione di un'applicazione AWS end-to-end.
</body>
</html>

Passo 1: Salva questo codice con il nome index.html e comprimi il file. Ora andiamo a distribuirlo in AWS Amplify. Vai alla console di gestione AWS e cerca AWS Amplify.

Passo 2: Vogliamo ospitare l’app web qui, quindi seleziona Amplify Hosting.

Passo 3: Non abbiamo un provider Git, quindi seleziona “Deploy senza Git Provider” e continua.

Passo 4: Dai un nome a scelta all’applicazione. Io chiamerò la mia “PasswordGeneratorFrontend”. Dai un nome all’ambiente. Seleziona “drag and drop” e prendi il file zip che abbiamo creato in precedenza, quindi clicca su salva e deploy.

Ora vedrai che il deploy è riuscito e otterrai il link alla pagina web ospitata. Puoi accedere a questo link in qualsiasi momento andando alla gestione del dominio nella barra laterale.

Abbiamo una pagina web attiva a cui gli utenti possono accedere nella nostra applicazione.

Configurazione di un servizio AWS Lambda per eseguire i calcoli nella nostra applicazione

Come potresti sapere, una funzione lambda è solo un pezzo di codice che viene eseguito in risposta a un qualche trigger, ad esempio quando carichi un’immagine in un bucket s3, questo potrebbe attivare una funzione lambda per elaborare l’immagine in una miniatura o qualcosa del genere, è solo un codice o delle funzioni che si trovano in AWS che vengono eseguite quando ne hai bisogno. Queste sono senza server, il che significa che non è necessario configurare e gestire server per eseguire il codice; avviene automaticamente dietro le quinte per te. Quindi, scriveremo un po’ di codice Python e faremo i calcoli di cui abbiamo bisogno.

Passo 1: Vai alla console di AWS e vai a lambda.

Passo 2: Crea una nuova funzione e seleziona “crea da zero”, che dovrebbe essere già impostato come predefinito, quindi dai un nome alla funzione. Quindi seleziona l’ambiente di runtime, scegliamo la versione più recente disponibile di Python. Puoi lasciare tutto il resto uguale e fare clic su crea funzione.

Passo 3: Ora scorri verso il basso nella console e vedrai un editor per scrivere il codice. Inseriremo il nostro codice Python in quell’editor. Di seguito è riportato il nostro codice Python:

import json
import random
import string

def lambda_handler(event, context):
    # Estrai i parametri di input dall'oggetto evento
    name = event['name']
    length = int(event['length'])
    req_capital_letters = int(event['reqCapitalLetters'])
    req_small_letters = int(event['reqSmallLetters'])
    req_numbers = int(event['reqNumbers'])
    req_special_chars =int(event['reqSpecialChars'])
    # Genera la password
    password_chars = []
    allowed="" #caratteri consentiti
    # Includi un carattere da ogni insieme di caratteri selezionato
    if req_capital_letters:
        password_chars.append(random.choice(string.ascii_uppercase ))
        allowed=allowed+string.ascii_uppercase
    if req_small_letters:
        password_chars.append(random.choice(string.ascii_lowercase))
        allowed=allowed+string.ascii_lowercase
    if req_numbers:
        password_chars.append(random.choice(string.digits))
        allowed=allowed+string.digits
    if req_special_chars:
        password_chars.append(random.choice(string.punctuation))
        allowed=allowed+string.punctuation
    # Calcola la lunghezza rimanente per i caratteri casuali
    remaining_length = length - len(password_chars)
    # Genera caratteri casuali per la lunghezza rimanente
    password_chars.extend(random.choice(allowed) for _ in range(remaining_length))
    # Mescola i caratteri per rimuovere il bias dell'ordine
    random.shuffle(password_chars)
    # Concatena i caratteri per formare la password
    password = ''.join(password_chars)
    # Restituisci la password in una risposta JSON
    return {
        'statusCode': 200,
        'body': json.dumps('La tua password per '+name+' è: ' + password)
    }

Il codice è abbastanza semplice da capire. Stiamo solo importando il pacchetto di utilità JSON e le librerie di stringhe casuali di Python per generare caratteri casuali, quindi abbiamo il nostro gestore lambda; questo è comune a tutte le funzioni lambda, ed è qui che facciamo la maggior parte del lavoro. Come ricorderai, il nostro utente passerà il nome, la lunghezza e le proprietà della password (lettere maiuscole, lettere minuscole, numeri, caratteri speciali) come input. Prendiamo quei valori dall’oggetto evento e li memorizziamo nelle rispettive variabili. Quindi includiamo un carattere da ciascun insieme selezionato dall’utente. Quindi calcoliamo la lunghezza rimanente per la password e, in base a quella lunghezza, generiamo caratteri casuali per la lunghezza rimanente dagli insiemi selezionati dall’utente. Infine, restituiamo il risultato come oggetto JSON.

Assicurati di salvare questo codice (puoi semplicemente premere CTRL + S), e quindi, molto importante, devi anche distribuirlo facendo clic sul pulsante di distribuzione proprio lì.

Passo 4: Ora, testiamo la nostra funzione lambda per assicurarci che questa funzione stia funzionando correttamente. Fai clic sulla piccola freccia a discesa vicino al pulsante di test e fai clic su “Configura evento di test”.

Passo 5: Andiamo a configurare un evento di test; ci consente di passare alcuni dati di test per assicurarci che la funzione stia funzionando correttamente. Crea un nuovo evento e dai un nome all’evento. Nel JSON dell’evento, passeremo alcune proprietà di password casuali. Nel mio caso, ho dato una lunghezza della password pari a 10 e selezionato tutti gli insiemi di caratteri (1-selezionato, 0-non selezionato). Scorri verso il basso e quindi fai clic su Salva.

Passo 6: Abbiamo configurato correttamente l’evento di test; ora dobbiamo effettivamente eseguire il test, che possiamo fare facendo clic sul pulsante di test. Come puoi vedere, abbiamo ottenuto un codice di stato 200 e il risultato contiene almeno un carattere da tutti gli insiemi. Quindi, la nostra funzione lambda sta funzionando correttamente.

Fino ad ora, abbiamo una semplice pagina HTML ospitata utilizzando Amplify e una funzione lambda per implementare la funzionalità della nostra applicazione.

Creazione di un’API per invocare la funzionalità del generatore di password

Successivamente, abbiamo bisogno di un modo per invocare la funzionalità del nostro generatore di password o fondamentalmente invocare quella funzione lambda. I nostri utenti ovviamente non andranno nella console AWS come abbiamo appena fatto noi e la eseguiranno, quindi abbiamo bisogno di un endpoint pubblico o un URL che possa essere chiamato per attivare l’esecuzione della funzione lambda, e per questo, utilizzeremo il servizio API Gateway, questo è un servizio principale in AWS che possiamo utilizzare per creare le nostre API (interfacce di programmazione delle applicazioni), che siano esse API http, REST o WebSocket, è davvero il modo perfetto per invocare una funzione lambda. Creiamo un’API REST per la nostra funzione Lambda utilizzando API Gateway.

Passo 1: Vai alla Console AWS e cerca API Gateway.

Passo 2: Crea una nuova API facendo clic sul pulsante Crea API. Ora vai alla sezione API REST e fai clic sul pulsante Crea.

Passo 3: Seleziona REST e seleziona Nuova API, quindi devi dare un nome. Nel mio caso, sto dando “CallPasswordGenerator”. Puoi lasciare tutto il resto uguale e fare clic su “Crea API”.

Passaggio 4: Al momento abbiamo un’API vuota, non è stata integrata con alcuna funzione lambda. Facciamolo ora. Sulla barra laterale, assicurati di avere selezionato le risorse, quindi hai selezionato la barra, e quindi nel menu delle azioni, seleziona crea metodo. Il tipo di metodo sarà un post, poiché l’utente invierà dati ad AWS e quindi fai clic sul segno di spunta accanto al POST.

Passaggio 5: Per il tipo di integrazione, utilizzeremo una funzione lambda e diamo il nome alla nostra funzione lambda e quindi fai clic su salva.

Passaggio 6: Ora, una cosa importante è che dobbiamo abilitare CORS o la condivisione delle risorse tra origini diverse. Quindi vai al menu delle azioni e seleziona “Abilita CORS”. Consente a un’applicazione web in esecuzione in un’origine o dominio di accedere alle risorse in un’origine o dominio diverso perché la nostra applicazione web è in esecuzione su un dominio in Amplify. La nostra funzione lambda sarà in esecuzione su un altro dominio, quindi dobbiamo essere in grado di lavorare tra questi domini o origini, ecco perché stiamo facendo questo.

Lascia tutti i valori predefiniti e fai clic sul pulsante “Abilita CORS” in basso.

Passaggio 7: Effettuiamo il deploy dell’API in modo da poterla testare. Vai al menu delle azioni e seleziona “Deploy API”. Dovremo configurare un nuovo stage perché potresti avere diversi stage per lo sviluppo, il test e la produzione. Fai clic su “Deploy”.

Passaggio 8: Copia l’URL di invocazione che è apparso sullo schermo perché ne avremo bisogno in seguito, quindi apri il blocco note o ovunque tu voglia conservarlo. Funzionerà come il nostro URL del gateway API.

Passaggio 9: Andiamo a validare questa API. Vai su risorse nella barra laterale e seleziona POST. Fai clic sull’opzione Test. Questo ci permetterà di inviare i dati di test desiderati e mostrare la risposta corrispondente.

Passaggio 10: Abbiamo usato lo stesso formato per testare la funzione lambda. Passa le proprietà della password richieste nel formato JSON e fai clic sul pulsante di test. Possiamo vedere che la nostra API ha funzionato correttamente e abbiamo ricevuto la risposta, che contiene la nostra password e il codice di stato di successo.

Memorizzazione dei dati in un database

In realtà non è necessario memorizzare i risultati da nessuna parte, potremmo restituirli all’utente, ma la maggior parte delle app del mondo reale ha dei database. Quindi, dobbiamo configurare un database e inoltre dobbiamo gestire le autorizzazioni tra le diverse parti dell’applicazione, in particolare dobbiamo dare alla nostra funzione lambda il permesso di scrivere nel database. Iniziamo con il database, useremo DynamoDB, un database chiave-valore o NoSQL che generalmente sarà più leggero rispetto a un database relazionale, dove è necessario configurare lo schema e le relazioni in anticipo.

Passaggio 1: Vai alla console, cerca DynamoDB e clicca su Crea una tabella.

Passaggio 2: Dai un nome alla tabella; per la chiave di partizione, chiamiamola ‘ID’. Puoi lasciare tutto il resto uguale e creare la tabella.

Passaggio 3: Ora dobbiamo salvare il nome della risorsa Amazon o l’ARN; per farlo, clicca sul nome della tabella e sotto informazioni generali, in additionalinfo, puoi trovare l’ARN. Salva questo ARN. Torneremo indietro e lo prenderemo più tardi.

Passaggio 4: Per dare i permessi di scrittura alla funzione lambda, vai al servizio lambda e vai alla scheda di configurazione, quindi devi fare clic sul nome del ruolo nell’esecuzione del ruolo. Questo dovrebbe aprirsi in una nuova scheda.

Passaggio 5: In sostanza, dobbiamo aggiungere alcuni permessi a quelli che questo ruolo ha già. Per farlo, fai clic su Aggiungi permessi e crea una politica inline.

Passaggio 6: Lavorare con il codice JSON è più facile, quindi fai clic sulla scheda JSON. Metti questo codice in quella scheda.

{
"Version": "2012-10-17",
"Statement": [
    {
        "Sid": "VisualEditor0",
        "Effect": "Allow",
        "Action": [
            "dynamodb:PutItem",
            "dynamodb:DeleteItem",
            "dynamodb:GetItem",
            "dynamodb:Scan",
            "dynamodb:Query",
            "dynamodb:UpdateItem"
        ],
        "Resource": "YOUR-TABLE-ARN"
    }
    ]
}

Consente tutte queste azioni specificate in JSON in modo che la funzione lambda abbia il permesso di fare tutte queste cose sulla nostra tabella DynamoDB. Tuttavia, è molto importante aggiornare l’ARN della tabella che hai copiato e fare clic su Review Policy.

Passaggio 7: Ora, assegna un nome a questa policy e, infine, crea una policy.

Passaggio 8: Dobbiamo aggiornare il codice Python della funzione lambda per interagire con il database. Il nostro codice precedente non ha questa funzionalità.

import json
import random
import string
# importa l'AWS SDK (per Python il nome del pacchetto è boto3)
import boto3
# crea un oggetto DynamoDB usando l'AWS SDK
dynamodb = boto3.resource('dynamodb')
# utilizza l'oggetto DynamoDB per selezionare la nostra tabella
table = dynamodb.Table('PasswordDatabase')
def lambda_handler(event, context):
    # Estrai i parametri di input dall'oggetto evento
    name = event['name']
    length = int(event['length'])
    req_capital_letters = int(event['reqCapitalLetters'])
    req_small_letters = int(event['reqSmallLetters'])
    req_numbers = int(event['reqNumbers'])
    req_special_chars =int(event['reqSpecialChars'])
    # Genera la password
    password_chars = []
    allowed="" #caratteri consentiti
    # Includi un carattere da ciascun set di caratteri selezionato
    if req_capital_letters:
        password_chars.append(random.choice(string.ascii_uppercase ))
        allowed=allowed+string.ascii_uppercase
    if req_small_letters:
        password_chars.append(random.choice(string.ascii_lowercase))
        allowed=allowed+string.ascii_lowercase
    if req_numbers:
        password_chars.append(random.choice(string.digits))
        allowed=allowed+string.digits
    if req_special_chars:
        password_chars.append(random.choice(string.punctuation))
        allowed=allowed+string.punctuation
    # Calcola la lunghezza rimanente per i caratteri casuali
    remaining_length = length - len(password_chars)
    # Genera caratteri casuali per la lunghezza rimanente
    password_chars.extend(random.choice(allowed) for _ in range(remaining_length))
    # Mescola i caratteri per rimuovere il bias dell'ordine
    random.shuffle(password_chars)
    # Concatena i caratteri per formare la password
    password = ''.join(password_chars)
    
    # scrivi il risultato nella tabella DynamoDB utilizzando l'oggetto che abbiamo istanziato
    response = table.put_item(
        Item={
            'ID': name,
            'Password':password
            })

    # Restituisci la password in una risposta JSON
    return {
        'statusCode': 200,
        'body': json.dumps('La tua password per '+name+' è: ' + password)
    }

Cosa c’è di nuovo qui in questo codice è che abbiamo importato un modulo per l’SDK (Software Development Kit) di AWS chiamato boto3, e poi otteniamo il nostro oggetto risorsa boto3 per DynamoDB. Successivamente, utilizziamo questo oggetto per connettere la nostra tabella DynamoDB passando il nome della tabella; il resto è lo stesso di prima. Infine, il codice inserisce il nome della password e la password generata nella tabella utilizzando la funzione table.put_item().

Passaggio 9: Assicurati di salvare questo codice con CTRL+S e, molto importante, assicurati di distribuire questo codice, quindi testiamolo premendo il pulsante di test. Possiamo vedere che il nostro codice funziona bene e fornisce il risultato corretto.

Passaggio 10: Verifichiamo se questi risultati sono aggiornati nella tabella DynamoDB andando a esplorare gli elementi della tabella, che mostrerà ciò che è stato memorizzato.

Possiamo vedere che abbiamo un nuovo risultato nella tabella, questo risultato è stato appena ottenuto eseguendo il test per la funzione lambda.

Collegare il Frontend al Backend

Al momento, siamo in grado di scrivere cose nella tabella DynamoDB e abbiamo le autorizzazioni corrette sulla funzione lambda, ma potresti aver notato che manca una connessione tra Amplify e il gateway API. Attualmente, dalla nostra pagina index.html, non c’è modo di attivare la nostra funzione lambda. Quindi, lavoriamo su questo pezzo finale.

Dobbiamo aggiornare la pagina index.html per chiamare il gateway API. Ecco il link al codice finale di index.html.

Spiegazione del codice: Inizialmente, nella sezione di stile, abbiamo fatto un po’ di styling per ottenere un aspetto migliore per gli elementi h1, gli input e i form sulla nostra pagina web. Puoi modificare e aggiornare il CSS in base alle tue preferenze. Abbiamo un elemento h1, “Password Generator”, nella sezione del body. Questo sarà il titolo della nostra pagina web. Successivamente, abbiamo un form in cui l’utente inserirà il nome e le proprietà della password utilizzando delle caselle di controllo, e abbiamo un pulsante per inviare il form, che richiama la funzione “call API” definita nel tag script. Passiamo il nome e la lunghezza della password come parametri a questa funzione. In questa funzione, inizializziamo i valori delle proprietà come 0 o 1 in base all’input dell’utente nel form.

Creiamo un oggetto JSON con questi valori e chiamiamo l’endpoint passando questo oggetto nel corpo della richiesta. Infine, visualizziamo un alert nel browser che mostra la risposta dal gateway API.

Ora dobbiamo ridistribuire la nostra pagina index.html utilizzando Amplify. Creiamo nuovamente un file zip di questo file. Apri Amplify e trascina e rilascia il file zip. Dovrebbe essere distribuito in pochi secondi e otterremo il link all’applicazione ospitata.

Basta aprire il link. Possiamo vedere che la nostra applicazione è stata distribuita con successo.

Eccoci qui; il risultato è stato aggiornato con successo nel nostro database DynamoDB.

Elimina le tue risorse

Se hai seguito tutto, elimina tutto ciò che abbiamo creato in questo articolo. Tutto dovrebbe essere nella versione gratuita, nel caso in cui non desideri alcuna sorpresa alla fine del mese.

Passaggio 1: Vai alla tua risorsa di Amplify, vai su azioni in alto a destra e fai clic su elimina app. Dovrai confermare l’operazione prima della cancellazione.

Passaggio 2: Successivamente, vai su DynamoDB e fai clic su tabelle. Seleziona la tabella e fai clic su elimina. Anche qui è necessaria una conferma prima della cancellazione.

Passaggio 3: Dopo, puoi eliminare la tua funzione lambda. Vai su AWS Lambda, seleziona funzioni nella barra laterale e quindi seleziona il nome della tua funzione. Quindi vai al menu a tendina delle azioni e fai clic su elimina.

Passaggio 4: Infine, API gateway. Seleziona il nome dell’API e sotto azioni, fai clic su elimina.

Conclusione

In questo articolo, abbiamo implementato un’applicazione web end-to-end utilizzando vari servizi AWS. In questa applicazione, gli utenti possono inserire il nome e le proprietà della password su una pagina web ospitata e distribuita utilizzando AWS Amplify. Quando l’utente invia i dettagli della password, lo script nella pagina web chiama l’API gateway passando i dati dell’utente nel corpo della richiesta, che attiva la funzione lambda di AWS, che effettua il calcolo e crea la password in base all’input dell’utente. Il risultato viene scritto nel database DynamoDB di AWS e quindi otterremo un messaggio restituito nel browser tramite l’API gateway. Abbiamo visto l’intero processo di creazione di un’API gateway, creazione della funzione Lambda, configurazione del database e assegnazione dei permessi dell’utente per la scrittura nel database da parte della funzione Lambda. Sebbene l’esempio sia relativamente semplice, copre componenti essenziali richieste per applicazioni reali più complesse.

Punti chiave

  1. AWS Amplify ci aiuta a creare e ospitare facilmente pagine web, rendendolo ideale per i front-end developer.
  2. AWS Lambda agisce come servizio backend serverless che invoca il nostro codice in risposta a trigger senza la necessità di gestire server.
  3. API Gateway aiuta a collegare vari servizi in un’applicazione web fornendo un endpoint.
  4. DynamoDB può memorizzare i risultati generati dalla funzione Lambda in formato JSON utilizzando gli SDK appropriati.
  5. Configurare le autorizzazioni e configurare le politiche necessarie per i servizi AWS è fondamentale per garantire il corretto funzionamento dell’applicazione.

Domande frequenti

I media mostrati in questo articolo non sono di proprietà di Analytics Vidhya e vengono utilizzati a discrezione dell’autore.