Erstellen eines serverlosen Kontaktformulars für Ihre statische Website

Veröffentlicht: 2022-03-10
Kurze Zusammenfassung ↬ Mit Hilfe dieses Artikels werden Sie endlich in der Lage sein, die Grundlagen von Amazon Web Services (AWS) Lambda und Simple Email Service (SES) APIs zu erlernen, um Ihnen dabei zu helfen, Ihren eigenen Mailer für statische Sites auf dem Serverless Framework zu erstellen. Lass uns anfangen!

Statische Website-Generatoren bieten eine schnelle und einfache Alternative zu Content-Management-Systemen (CMS) wie WordPress. Es gibt kein Server- oder Datenbank-Setup, nur einen Build-Prozess und einfaches HTML, CSS und JavaScript. Leider stößt man ohne Server schnell an seine Grenzen. Zum Beispiel beim Hinzufügen eines Kontaktformulars.

Mit dem Aufkommen der serverlosen Architektur muss das Hinzufügen eines Kontaktformulars zu Ihrer statischen Website nicht mehr der Grund sein, zu einem CMS zu wechseln. Es ist möglich, das Beste aus beiden Welten zu bekommen: eine statische Site mit einem serverlosen Back-End für das Kontaktformular (das Sie nicht pflegen müssen). Das Beste ist vielleicht, dass auf Websites mit geringem Datenverkehr, wie z. B. Portfolios, die hohen Limits vieler Serverless-Anbieter diese Dienste völlig kostenlos machen!

In diesem Artikel lernen Sie die Grundlagen von Amazon Web Services (AWS) Lambda und Simple Email Service (SES) APIs kennen, um Ihren eigenen statischen Site-Mailer auf dem Serverless Framework zu erstellen. Der vollständige Service nimmt Formulardaten entgegen, die von einer AJAX-Anfrage übermittelt werden, trifft auf den Lambda-Endpunkt, parst die Daten, um die SES-Parameter zu erstellen, sendet die E-Mail-Adresse und gibt eine Antwort für unsere Benutzer zurück. Ich führe Sie durch die erstmalige Einrichtung von Serverless durch die Bereitstellung. Es sollte weniger als eine Stunde dauern, bis es fertig ist, also fangen wir an!

Das statische Site-Formular, das die Nachricht an den Lambda-Endpunkt sendet und eine Antwort an den Benutzer zurücksendet.
Das statische Site-Formular, das die Nachricht an den Lambda-Endpunkt sendet und eine Antwort an den Benutzer zurücksendet.
Mehr nach dem Sprung! Lesen Sie unten weiter ↓

Einrichten

Es gibt minimale Voraussetzungen für den Einstieg in die serverlose Technologie. Für unsere Zwecke ist es einfach eine Knotenumgebung mit Yarn, dem Serverless Framework und einem AWS-Konto.

Einrichten des Projekts

Die Serverless Framework-Website. Nützlich für Installation und Dokumentation.
Die Serverless Framework-Website. Nützlich für Installation und Dokumentation.

Wir verwenden Yarn, um das Serverless Framework in einem lokalen Verzeichnis zu installieren.

  1. Erstellen Sie ein neues Verzeichnis zum Hosten des Projekts.
  2. Navigieren Sie in Ihrer Befehlszeilenschnittstelle zu dem Verzeichnis.
  3. Führen Sie wool yarn init aus, um eine package.json -Datei für dieses Projekt zu erstellen.
  4. Führen Sie yarn add serverless aus, um das Framework lokal zu installieren.
  5. Führen yarn serverless create --template aws-nodejs --name static-site-mailer , um eine Node-Service-Vorlage zu erstellen, und nennen Sie sie static-site-mailer .

Unser Projekt ist eingerichtet, aber wir können nichts tun, bis wir unsere AWS-Services eingerichtet haben.

Einrichten eines Amazon Web Services-Kontos, von Anmeldeinformationen und eines einfachen E-Mail-Dienstes

Die Anmeldeseite von Amazon Web Services, die ein großzügiges kostenloses Kontingent enthält, wodurch unser Projekt völlig kostenlos ist.
Die Anmeldeseite von Amazon Web Services, die ein großzügiges kostenloses Kontingent enthält, wodurch unser Projekt völlig kostenlos ist.

Das Serverless Framework hat eine Videoanleitung zum Einrichten von AWS-Anmeldeinformationen aufgezeichnet, aber ich habe die Schritte auch hier aufgelistet.

  1. Registrieren Sie sich für ein AWS-Konto oder melden Sie sich an, wenn Sie bereits eines haben.
  2. Suchen Sie in der AWS-Suchleiste nach „IAM“.
  3. Klicken Sie auf der IAM-Seite in der Seitenleiste auf „Benutzer“ und dann auf die Schaltfläche „Benutzer hinzufügen“.
  4. Geben Sie dem Benutzer auf der Seite „Benutzer hinzufügen“ einen Namen – so etwas wie „serverlos“ ist angemessen. Aktivieren Sie „Programmatischer Zugriff“ unter „Zugriffstyp“ und klicken Sie dann auf „Weiter“.
  5. Klicken Sie auf dem Berechtigungsbildschirm auf die Registerkarte „Vorhandene Richtlinien direkt anhängen“, suchen Sie in der Liste nach „AdministratorAccess“, aktivieren Sie es und klicken Sie auf „Weiter“.
  6. Auf dem Überprüfungsbildschirm sollten Sie Ihren Benutzernamen mit „Programmatischer Zugriff“ und „AdministratorAccess“ sehen und dann den Benutzer erstellen.
  7. Der Bestätigungsbildschirm zeigt die „Zugriffsschlüssel-ID“ und den „Geheimen Zugriffsschlüssel“ des Benutzers an, die Sie benötigen, um dem Serverless Framework Zugriff zu gewähren. Geben Sie in Ihrer CLI yarn sls config credentials --provider aws --key YOUR_ACCESS_KEY_ID --secret YOUR_SECRET_ACCESS_KEY und ersetzen YOUR_ACCESS_KEY_ID und YOUR_SECRET_ACCESS_KEY durch die Schlüssel auf dem Bestätigungsbildschirm.

Ihre Anmeldeinformationen sind jetzt konfiguriert, aber während wir uns in der AWS-Konsole befinden, richten wir den einfachen E-Mail-Service ein.

  1. Klicken Sie oben links auf Konsolenstartseite, um nach Hause zu gehen.
  2. Suchen Sie auf der Startseite in der AWS-Suchleiste nach „Simple Email Service“.
  3. Klicken Sie auf der SES-Startseite in der Seitenleiste auf „E-Mail-Adressen“.
  4. Klicken Sie auf der Listenseite der E-Mail-Adressen auf die Schaltfläche „Neue E-Mail-Adresse bestätigen“.
  5. Geben Sie im Dialogfenster Ihre E-Mail-Adresse ein und klicken Sie dann auf „Diese E-Mail-Adresse bestätigen“.
  6. Sie erhalten in Kürze eine E-Mail mit einem Link zur Bestätigung der Adresse. Klicken Sie auf den Link, um den Vorgang abzuschließen.

Nachdem unsere Konten erstellt wurden, werfen wir einen Blick auf die Serverless-Vorlagendateien.

Einrichten des serverlosen Frameworks

Beim Ausführen von serverless create werden zwei Dateien erstellt: handler.js, die die Lambda-Funktion enthält, und serverless.yml, die Konfigurationsdatei für die gesamte serverlose Architektur. Innerhalb der Konfigurationsdatei können Sie beliebig viele Handler angeben, und jeder wird einer neuen Funktion zugeordnet, die mit anderen Funktionen interagieren kann. In diesem Projekt erstellen wir nur einen einzigen Handler, aber in einer vollständigen serverlosen Architektur hätten Sie mehrere der verschiedenen Funktionen des Dienstes.

Die vom Serverless Framework generierte Standarddateistruktur mit handler.js und serverless.yml.
Die vom Serverless Framework generierte Standarddateistruktur mit handler.js und serverless.yml.

In handler.js sehen Sie eine einzelne exportierte Funktion namens hello . Dies ist derzeit die wichtigste (und einzige) Funktion. Zusammen mit allen Node-Handlern benötigt es drei Parameter:

  • event
    Dies kann man sich als Eingabedaten für die Funktion vorstellen.
  • context object
    Diese enthält die Laufzeitinformationen der Lambda-Funktion.
  • callback
    Ein optionaler Parameter, um Informationen an den Aufrufer zurückzugeben.
 // handler.js 'use strict'; module.exports.hello = (event, context, callback) => { const response = { statusCode: 200, body: JSON.stringify({ message: 'Go Serverless v1.0! Your function executed successfully!', input: event, }), }; callback(null, response); };

Am Ende von hello steht ein Rückruf. Es ist ein optionales Argument, um eine Antwort zurückzugeben, aber wenn es nicht explizit aufgerufen wird, wird es implizit mit null zurückgegeben. Der Callback benötigt zwei Parameter:

  • Fehler Fehler
    Zum Bereitstellen von Fehlerinformationen, wenn Lambda selbst fehlschlägt. Wenn Lambda erfolgreich ist, sollte null an diesen Parameter übergeben werden.
  • Objektergebnis
    Zum Bereitstellen eines Response-Objekts. Es muss JSON.stringify kompatibel sein. Wenn das Fehlerfeld einen Parameter enthält, wird dieses Feld ignoriert.

Unsere statische Website sendet unsere Formulardaten im Ereignistext und der Rückruf gibt eine Antwort zurück, die unser Benutzer sehen kann.

In serverless.yml sehen Sie den Namen des Dienstes, Anbieterinformationen und die Funktionen.

 # serverless.yml service: static-site-mailer provider: name: aws runtime: nodejs6.10 functions: hello: handler: handler.hello 
Zuordnung der Funktionsnamen in serverless.yml zu handler.js.
Zuordnung der Funktionsnamen in serverless.yml zu handler.js.

Beachten Sie die Zuordnung zwischen der Hello-Funktion und dem Handler? Wir können unsere Datei beliebig benennen und funktionieren, und solange sie der Konfiguration entspricht, wird sie funktionieren. Benennen wir unsere Funktion in staticSiteMailer um.

 # serverless.yml functions: staticSiteMailer: handler: handler.staticSiteMailer
 // handler.js module.exports.staticSiteMailer = (event, context, callback) => { ... };

Lambda-Funktionen benötigen die Berechtigung, mit anderer AWS-Infrastruktur zu interagieren. Bevor wir eine E-Mail senden können, müssen wir SES dies erlauben. Fügen Sie in serverless.yml unter provider.iamRoleStatements die Berechtigung hinzu.

 # serverless.yml provider: name: aws runtime: nodejs6.10 iamRoleStatements: - Effect: "Allow" Action: - "ses:SendEmail" Resource: ["*"]

Da wir eine URL für unsere Formularaktion benötigen, müssen wir unserer Funktion HTTP-Ereignisse hinzufügen. In serverless.yml erstellen wir einen Pfad, geben die Methode als post an und setzen CORS aus Sicherheitsgründen auf true.

 functions: staticSiteMailer: handler: handler.staticSiteMailer events: - http: method: post path: static-site-mailer cors: true

Unsere aktualisierten serverless.yml- und handler.js-Dateien sollten wie folgt aussehen:

 # serverless.yml service: static-site-mailer provider: name: aws runtime: nodejs6.10 functions: staticSiteMailer: handler: handler.staticSiteMailer events: - http: method: post path: static-site-mailer cors: true provider: name: aws runtime: nodejs6.10 iamRoleStatements: - Effect: "Allow" Action: - "ses:SendEmail" Resource: ["*"]
 // handler.js 'use strict'; module.exports.staticSiteMailer = (event, context, callback) => { const response = { statusCode: 200, body: JSON.stringify({ message: 'Go Serverless v1.0! Your function executed successfully!', input: event, }), }; callback(null, response); };

Unsere serverlose Architektur ist eingerichtet, also stellen wir sie bereit und testen sie. Sie erhalten eine einfache JSON-Antwort.

 yarn sls deploy --verbose yarn sls invoke --function staticSiteMailer { "statusCode": 200, "body": "{\"message\":\"Go Serverless v1.0! Your function executed successfully!\",\"input\":{}}" } 
Die Antwort auf den Aufruf unserer brandneuen serverlosen Funktion.
Die Antwort auf den Aufruf unserer brandneuen serverlosen Funktion.

Erstellen des HTML-Formulars

Die Eingabe unserer Lambda-Funktion und die Ausgabe des Formulars müssen übereinstimmen. Bevor wir also die Funktion erstellen, erstellen wir das Formular und erfassen dessen Ausgabe. Wir halten es mit Namens-, E-Mail- und Nachrichtenfeldern einfach. Wir fügen die Formularaktion hinzu, sobald wir unsere serverlose Architektur bereitgestellt und unsere URL erhalten haben, aber wir wissen, dass es sich um eine POST-Anforderung handeln wird, damit wir sie hinzufügen können. Am Ende des Formulars fügen wir ein Absatz-Tag zur Anzeige hinzu Antwortnachrichten an den Benutzer, die wir beim Übermittlungsrückruf aktualisieren.

 <form action="{{ SERVICE URL }}" method="POST"> <label> Name <input type="text" name="name" required> </label> <label> Email <input type="email" name="reply_to" required> </label> <label> Message: <textarea name="message" required></textarea> </label> <button type="submit">Send Message</button> </form> <p></p>

Um die Ausgabe zu erfassen, fügen wir dem Formular einen Submit-Handler hinzu, wandeln unsere Formularparameter in ein Objekt um und senden stringifiziertes JSON an unsere Lambda-Funktion. In der Lambda-Funktion verwenden wir JSON.parse() , um unsere Daten zu lesen. Alternativ können Sie Serialize oder query-string von jQuery verwenden, um die Formularparameter als Abfragezeichenfolge zu senden und zu analysieren, aber JSON.stringify() und JSON.parse() sind nativ.

 (() => { const form = document.querySelector('form'); const formResponse = document.querySelector('js-form-response'); form.onsubmit = e => { e.preventDefault(); // Prepare data to send const data = {}; const formElements = Array.from(form); formElements.map(input => (data[input.name] = input.value)); // Log what our lambda function will receive console.log(JSON.stringify(data)); }; })();

Senden Sie Ihr Formular ab und erfassen Sie dann die Konsolenausgabe. Wir werden es als nächstes in unserer Lambda-Funktion verwenden.

Erfassen der Formulardaten in einem Konsolenprotokoll.
Erfassen der Formulardaten in einem Konsolenprotokoll.

Aufrufen von Lambda-Funktionen

Besonders während der Entwicklung müssen wir testen, ob unsere Funktion das tut, was wir erwarten. Das Serverless Framework stellt den Befehl invoke und invoke invoke local bereit, um Ihre Funktion von Live- bzw. Entwicklungsumgebungen auszulösen. Beide Befehle erfordern die Übergabe des Funktionsnamens, in unserem Fall staticSiteMailer .

 yarn sls invoke local --function staticSiteMailer

Um Scheindaten an unsere Funktion zu übergeben, erstellen Sie eine neue Datei namens data.json mit der erfassten Konsolenausgabe unter einem body innerhalb eines JSON-Objekts. Es sollte in etwa so aussehen:

 // data.json { "body": "{\"name\": \"Sender Name\",\"reply_to\": \"[email protected]\",\"message\": \"Sender message\"}" }

Um die Funktion mit den lokalen Daten aufzurufen, übergeben Sie das Argument --path zusammen mit dem Pfad zur Datei.

 yarn sls invoke local --function staticSiteMailer --path data.json 
Eine aktualisierte Antwort von unserer serverlosen Funktion, wenn wir ihr JSON-Daten übergeben.
Eine aktualisierte Antwort von unserer serverlosen Funktion, wenn wir ihr JSON-Daten übergeben.

Sie sehen eine ähnliche Antwort wie zuvor, aber die input enthält das Ereignis, das wir verspottet haben. Lassen Sie uns unsere Scheindaten verwenden, um eine E-Mail mit dem einfachen E-Mail-Dienst zu senden!

Senden einer E-Mail mit dem einfachen E-Mail-Dienst

Wir werden die staticSiteMailer Funktion durch einen Aufruf einer privaten sendEmail Funktion ersetzen. Im Moment können Sie den Vorlagencode auskommentieren oder entfernen und ihn ersetzen durch:

 // hander.js function sendEmail(formData, callback) { // Build the SES parameters // Send the email } module.exports.staticSiteMailer = (event, context, callback) => { const formData = JSON.parse(event.body); sendEmail(formData, function(err, data) { if (err) { console.log(err, err.stack); } else { console.log(data); } }); };

Zuerst analysieren wir event.body , um die Formulardaten zu erfassen, und übergeben sie dann an eine private sendEmail Funktion. sendEmail ist für das Senden der E-Mail verantwortlich, und die Callback-Funktion gibt eine Fehler- oder Erfolgsantwort mit err oder data zurück. In unserem Fall können wir den Fehler oder die Daten einfach protokollieren, da wir diese gleich durch den Lambda-Callback ersetzen werden.

Amazon bietet ein praktisches SDK, aws-sdk , um seine Dienste mit Lambda-Funktionen zu verbinden. Viele ihrer Dienste, einschließlich SES, sind Teil davon. Wir fügen es dem Projekt mit yarn add aws-sdk und importieren es in die oberste Handler-Datei.

 // handler.js const AWS = require('aws-sdk'); const SES = new AWS.SES();

In unserer privaten sendEmail Funktion bauen wir die SES.sendEmail Parameter aus den geparsten Formulardaten auf und verwenden den Callback, um eine Antwort an den Aufrufer zurückzugeben. Die Parameter benötigen als Objekt:

  • Quelle
    Die E-Mail-Adresse, von der SES sendet.
  • ReplyToAddresses
    Ein Array von E-Mail-Adressen, die der Antwort auf das Feld in der E-Mail hinzugefügt wurden.
  • Ziel
    Ein Objekt, das mindestens eine ToAddresses , CcAddresses oder BccAddresses enthalten muss. Jedes Feld enthält eine Reihe von E-Mail-Adressen, die den Feldern to , cc und bcc entsprechen.
  • Nachricht
    Ein Objekt, das Body und Subject enthält.

Da formData ein Objekt ist, können wir unsere Formularfelder direkt wie formData.message , unsere Parameter erstellen und senden. Wir leiten Ihre SES-verifizierte E-Mail an Source and Destination.ToAddresses weiter. Solange die E-Mail verifiziert ist, können Sie hier alles übergeben, einschließlich verschiedener E-Mail-Adressen. Wir pflücken unser reply_to , message und name aus unserem formData -Objekt, um die Felder ReplyToAddresses und Message.Body.Text.Data .

 // handler.js function sendEmail(formData, callback) { const emailParams = { Source: '[email protected]', // SES SENDING EMAIL ReplyToAddresses: [formData.reply_to], Destination: { ToAddresses: ['[email protected]'], // SES RECEIVING EMAIL }, Message: { Body: { Text: { Charset: 'UTF-8', Data: `${formData.message}\n\nName: ${formData.name}\nEmail: ${formData.reply_to}`, }, }, Subject: { Charset: 'UTF-8', Data: 'New message from your_site.com', }, }, }; SES.sendEmail(emailParams, callback); }

SES.sendEmail sendet die E-Mail und unser Rückruf gibt eine Antwort zurück. Beim Aufrufen der lokalen Funktion wird eine E-Mail an Ihre verifizierte Adresse gesendet.

 yarn sls invoke local --function staticSiteMailer --path data.json 
Die Rückantwort von SES.sendEmail, wenn es erfolgreich ist.
Die Rückantwort von SES.sendEmail , wenn es erfolgreich ist.

Zurückgeben einer Antwort vom Handler

Unsere Funktion sendet eine E-Mail über die Befehlszeile, aber so werden unsere Benutzer nicht damit interagieren. Wir müssen eine Antwort auf unsere AJAX-Formularübermittlung zurücksenden. Wenn dies fehlschlägt, sollten wir einen entsprechenden statusCode sowie die err.message . Wenn es erfolgreich ist, ist der 200 statusCode ausreichend, aber wir geben die Mailer-Antwort auch im Body zurück. In staticSiteMailer bauen wir unsere Antwortdaten auf und ersetzen unsere sendEmail Callback-Funktion durch den Lambda-Callback.

 // handler.js module.exports.staticSiteMailer = (event, context, callback) => { const formData = JSON.parse(event.body); sendEmail(formData, function(err, data) { const response = { statusCode: err ? 500 : 200, headers: { 'Content-Type': 'application/json', 'Access-Control-Allow-Origin': 'https://your-domain.com', }, body: JSON.stringify({ message: err ? err.message : data, }), }; callback(null, response); }); };

Unser Lambda-Callback gibt jetzt sowohl Erfolgs- als auch Fehlermeldungen von SES.sendEmail . Wir erstellen die Antwort mit Überprüfungen, ob err vorhanden ist, damit unsere Antwort konsistent ist. Die Lambda-Callback-Funktion selbst übergibt null im Fehlerargumentfeld und die Antwort als zweites. Wir wollen Fehler weitergeben, aber wenn Lambda selbst fehlschlägt, wird sein Rückruf implizit mit der Fehlerantwort aufgerufen.

In den headers müssen Sie Access-Control-Allow-Origin durch Ihre eigene Domain ersetzen. Dadurch wird verhindert, dass andere Domains Ihren Service nutzen und möglicherweise eine AWS-Rechnung in Ihrem Namen anhäufen! Und ich gehe in diesem Artikel nicht darauf ein, aber es ist möglich, Lambda so einzurichten, dass es Ihre eigene Domain verwendet. Sie müssen ein SSL/TLS-Zertifikat auf Amazon hochladen. Das Serverless Framework-Team hat dazu ein fantastisches Tutorial geschrieben.

Beim Aufrufen der lokalen Funktion wird nun eine E-Mail gesendet und die entsprechende Antwort zurückgegeben.

 yarn sls invoke local --function staticSiteMailer --path data.json 
Die Rückantwort von unserer serverlosen Funktion, die die SES.sendEmail-Rückantwort im Text enthält.
Die Rückantwort von unserer serverlosen Funktion, die die SES.sendEmail-Rückantwort im Text enthält.

Aufrufen der Lambda-Funktion aus dem Formular

Unser Service ist komplett! Um es bereitzustellen, führen Sie das yarn sls deploy -v . Nach der Bereitstellung erhalten Sie eine URL, die in etwa so aussieht wie https://r4nd0mh45h.execute-api.us-east-1.amazonaws.com/dev/static-site-mailer , die Sie der Formularaktion hinzufügen können. Als nächstes erstellen wir die AJAX-Anforderung und senden die Antwort an den Benutzer zurück.

 (() => { const form = document.querySelector('form'); const formResponse = document.querySelector('js-form-response'); form.onsubmit = e => { e.preventDefault(); // Prepare data to send const data = {}; const formElements = Array.from(form); formElements.map(input => (data[input.name] = input.value)); // Log what our lambda function will receive console.log(JSON.stringify(data)); // Construct an HTTP request var xhr = new XMLHttpRequest(); xhr.open(form.method, form.action, true); xhr.setRequestHeader('Accept', 'application/json; charset=utf-8'); xhr.setRequestHeader('Content-Type', 'application/json; charset=UTF-8'); // Send the collected data as JSON xhr.send(JSON.stringify(data)); // Callback function xhr.onloadend = response => { if (response.target.status === 200) { // The form submission was successful form.reset(); formResponse.innerHTML = 'Thanks for the message. I'll be in touch shortly.'; } else { // The form submission failed formResponse.innerHTML = 'Something went wrong'; console.error(JSON.parse(response.target.response).message); } }; }; })();

Im AJAX-Callback prüfen wir den Statuscode mit response.target.status . Wenn es etwas anderes als 200 ist, können wir dem Benutzer eine Fehlermeldung anzeigen, andernfalls lassen Sie ihn wissen, dass die Nachricht gesendet wurde. Da unser Lambda stringifiziertes JSON zurückgibt, können wir die Textnachricht mit JSON.parse(response.target.response).message . Es ist besonders nützlich, den Fehler zu protokollieren.

Sie sollten in der Lage sein, Ihr Formular vollständig von Ihrer statischen Website aus einzureichen!

Das statische Site-Formular, das die Nachricht an den Lambda-Endpunkt sendet und eine Antwort an den Benutzer zurücksendet.
Das statische Site-Formular, das die Nachricht an den Lambda-Endpunkt sendet und eine Antwort an den Benutzer zurücksendet.

Nächste Schritte

Das Hinzufügen eines Kontaktformulars zu Ihrer Statik ist mit dem Serverless Framework und AWS ganz einfach. Es gibt Raum für Verbesserungen in unserem Code, wie das Hinzufügen von Formularvalidierungen mit einem Honeypot, das Verhindern von AJAX-Aufrufen für ungültige Formulare und das Verbessern der UX der Antwort, aber das reicht für den Anfang. Sie können einige dieser Verbesserungen in dem statischen Site-Mailer-Repo sehen, das ich erstellt habe. Ich hoffe, ich habe Sie dazu inspiriert, Serverless selbst auszuprobieren!