Zum Inhalt springen
Zurück zu Tutorials

Ein serverloses Kontaktformular mit AWS SAM, Lambda und DynamoDB deployen

Fortgeschritten · 1 hour 30 minutes · 5 Min. Lesezeit · Byte Smith ·

Bevor du beginnst

  • Ein AWS-Konto mit Berechtigungen zum Erstellen von SAM-Stacks, Lambda-Funktionen, DynamoDB-Tabellen, API-Gateway-APIs und SES-Identitaeten
  • AWS CLI und SAM CLI installiert und konfiguriert
  • Node.js 22 lokal installiert
  • Eine verifizierte SES-Sender-Domain oder E-Mail-Adresse
  • Eine statische Website, der Sie ein Kontaktformular hinzufuegen moechten (Astro, Next.js, Hugo oder aehnlich)
  • Grundlegende Vertrautheit mit TypeScript und AWS CloudFormation

Was du lernen wirst

  • Eine vollstaendige Serverless-API mit SAM definieren, einschliesslich API Gateway, Lambda, DynamoDB und SES
  • Ein DynamoDB-Single-Table-Schema mit Composite-Keys, TTL und partitionsbasierter Multi-Tenancy entwerfen
  • Eingabevalidierung mit einem Schema-Registry-Muster implementieren
  • DynamoDB-gestuetztes Rate-Limiting mit Fail-Closed-Design hinzufuegen
  • SES-Bounces und -Beschwerden mit einer SNS-getriggerten Unterdrueckungsliste behandeln
  • CloudWatch-Metrikfilter und -Alarme fuer Produktions-Monitoring einrichten
  • Das Backend mit einem statischen Frontend unter Verwendung von Honeypot-Spam-Schutz integrieren
  • Mehrere Websites von einem einzelnen Deployment aus unterstuetzen mit einer Site-Registry
1
2
3
4
5
6
7
8
9
10
Auf dieser Seite

Dieses Tutorial fuehrt durch den Aufbau und das Deployment eines vollstaendigen serverlosen Kontaktformular-Backends mit AWS SAM. Das System behandelt die Formular-Einreichung, Eingabevalidierung, DynamoDB-gestuetztes Rate-Limiting, E-Mail-Benachrichtigungen ueber SES, Bounce-Behandlung und Monitoring — und es unterstuetzt mehrere Websites von einem einzelnen Deployment aus.

Die meisten “serverlosen Kontaktformular”-Tutorials decken eine einzelne Lambda-Funktion mit hartkodierten E-Mail-Adressen ab. Das reicht fuer einen persoenlichen Blog, aber es bricht fuer jede ernsthafte Nutzung zusammen. Dieses Tutorial baut eine produktionsreife Variante: Multi-Site-Support, anstaendige Validierung, Rate-Limiting, das Missbrauch tatsaechlich stoppt, Bounce-Behandlung, die Ihren SES-Ruf schuetzt, und Monitoring, das Ihnen sagt, wenn etwas bricht.

Der vollstaendige Quellcode ist auf GitHub unter serverless-contact-form verfuegbar.

Schritt 1: SAM-Projekt und Template einrichten

Das SAM-Template definiert die gesamte Infrastruktur: API Gateway, Lambda-Funktionen, DynamoDB-Tabellen, SES-Konfiguration und CloudWatch-Ressourcen. Das Projekt verwendet TypeScript fuer die Lambda-Funktionen und esbuild fuer schnelle Builds.

Das Template verwendet Parameter fuer die Konfiguration, damit Sie Staging- und Produktionsumgebungen aus demselben Template deployen koennen. Globale Funktionseinstellungen definieren Runtime, Timeout und Speicher fuer alle Lambda-Funktionen.

Projektstruktur

Die Projektstruktur folgt SAM-Konventionen:

  • template.yaml — SAM-Template mit allen Ressourcen
  • src/handlers/ — Lambda-Funktionshandler
  • src/lib/ — geteilte Bibliotheken (Validierung, Rate-Limiting, E-Mail)
  • src/config/ — Site-Registry und Schema-Definitionen
  • events/ — Test-Events fuer lokales Debugging

Lokale Entwicklung starten

sam build
sam local start-api

Schritt 2: DynamoDB-Schema entwerfen

Das Schema verwendet ein Single-Table-Design mit Composite-Keys fuer die Submissions-Tabelle und eine separate Tabelle fuer die E-Mail-Unterdrueckungsliste.

Submissions-Tabelle

Die Submissions-Tabelle verwendet siteId als Partition-Key und einen sortierten zusammengesetzten Sort-Key aus Zeitstempel und Submissions-ID. Das erlaubt effiziente Abfragen nach Site und Zeitbereich. TTL wird fuer automatische Bereinigung alter Einreichungen verwendet.

Fuer das Rate-Limiting wird ein separates Item-Muster im selben Table verwendet: Die IP-Adresse als Teil des Sort-Keys ermoeglicht das Zaehlen von Einreichungen pro IP in einem Zeitfenster.

Unterdrueckungstabelle

Die Unterdrueckungstabelle speichert E-Mail-Adressen, die Bounces oder Beschwerden erzeugt haben. Vor dem Senden einer E-Mail prueft die Sendefunktion diese Tabelle und ueberspringt Adressen, die unterdrueckt sind.

Schritt 3: Den Submit-Handler erstellen

Der Submit-Handler ist die Haupt-Lambda-Funktion, die Formular-Einreichungen verarbeitet. Er validiert die Eingabe, prueft Rate-Limits, speichert die Einreichung in DynamoDB und sendet Benachrichtigungen ueber SES.

Der Middleware-Ansatz trennt Bedenken sauber: Jeder Schritt (Validierung, Rate-Limiting, Speicherung, E-Mail) ist ein separates Modul, das unabhaengig getestet werden kann.

CORS-Konfiguration

Da das Formular-Frontend auf einer anderen Domain als die API gehostet wird, ist korrekte CORS-Konfiguration entscheidend. Die API gibt die richtigen Access-Control-Headers zurueck, einschliesslich Access-Control-Allow-Origin fuer die konfigurierten Domains.

Schritt 4: Validierung und Rate-Limiting hinzufuegen

Schema-Registry

Die Schema-Registry definiert, welche Felder jede Site akzeptiert und welche erforderlich sind. Das ermoeglicht verschiedene Formularstrukturen fuer verschiedene Websites, die vom selben Backend bedient werden.

Site-Registry

Die Site-Registry definiert, welche Websites das Formular-Backend verwenden duerfen. Jeder Site-Eintrag enthaelt:

  • erlaubte Domains fuer CORS
  • Empfaenger-E-Mail-Adressen
  • Rate-Limit-Konfiguration
  • Schema-Referenz

DynamoDB-gestuetztes Rate-Limiting

Das Rate-Limiting verwendet DynamoDB-Conditional-Writes, um Einreichungen pro IP-Adresse in einem gleitenden Zeitfenster zu zaehlen. Das Design ist fail-closed: Wenn der DynamoDB-Aufruf fehlschlaegt, wird die Einreichung abgelehnt, statt durchgelassen.

Schritt 5: SES-E-Mail-Benachrichtigungen einrichten

Zwei Arten von E-Mails werden gesendet:

  1. Admin-Benachrichtigung: Informiert den Site-Owner ueber eine neue Einreichung
  2. Benutzer-Bestaetigung: Bestaetigt dem Absender, dass seine Nachricht empfangen wurde

Beide verwenden HTML-Templates mit Pro-Site-Branding. Die Templates werden aus der Site-Konfiguration geladen, sodass jede Website ihre eigene Marke und Antwortadresse haben kann.

SES-Konfiguration

Stellen Sie sicher, dass Ihre Sender-Domain oder E-Mail-Adresse in SES verifiziert ist. Fuer Produktions-Nutzung beantragen Sie, SES aus dem Sandbox-Modus zu befreien.

Schritt 6: Bounces und Beschwerden behandeln

SES kann Benachrichtigungen senden, wenn E-Mails bouncen oder als Spam gemeldet werden. Der Stack konfiguriert SNS-Topics fuer Bounces und Beschwerden und eine Bounce-Handler-Lambda-Funktion, die:

  1. Die Bounce/Complaint-Benachrichtigung von SNS empfaengt
  2. Die betroffene E-Mail-Adresse in die Unterdrueckungstabelle eintraegt
  3. Einen Alarm ausloest, wenn Bounce-Raten steigen

Das schuetzt Ihren SES-Senderuf, der direkt beeinflusst, ob Ihre E-Mails zugestellt werden.

Schritt 7: Monitoring und Alarme hinzufuegen

CloudWatch-Metrikfilter extrahieren Schluesselmetriken aus den Lambda-Logs:

  • Fehlerzahl pro Funktion
  • Rate-Limit-Ablehnungen
  • Bounce-Zaehler
  • Auth-Fehler (ungueltige API-Keys oder unbekannte Sites)

CloudWatch-Alarme benachrichtigen ueber SNS, wenn Schwellenwerte ueberschritten werden.

Deployment

Deployen Sie den vollstaendigen Stack:

sam build
sam deploy --guided

Der Guided-Deploy fragt nach Parametern wie Stack-Name, Region und den konfigurierten Site-Domains.

Schritt 8: Das Frontend-Kontaktformular erstellen

Das Frontend ist ein einfaches HTML-Formular mit:

  • Client-seitiger Validierung fuer erforderliche Felder
  • Honeypot-Feld fuer Spam-Praevention (ein verstecktes Feld, das Bots ausfuellen, Menschen aber nicht)
  • Graceful Fehlerbehandlung mit benutzerfreundlichen Nachrichten
  • AJAX-Einreichung ohne Seitenneuladen

Das Honeypot-Feld ist die einfachste effektive Spam-Praevention: Wenn das versteckte Feld ausgefuellt ist, lehnt die API die Einreichung still ab. Das blockiert die meisten automatisierten Bots ohne CAPTCHA-Reibung fuer echte Benutzer.

Integration mit Ihrem Static-Site-Generator

Das Formular sendet eine POST-Anfrage an Ihren API-Gateway-Endpunkt. Fuer Astro, Next.js, Hugo oder jede andere statische Website fuegen Sie das Formular-HTML und das JavaScript ein und konfigurieren die API-URL als Umgebungsvariable.

Haeufige Einrichtungsprobleme

CORS-Fehler im Browser

Ursache: Die Domain des Frontends stimmt nicht mit der erlaubten Origin in der Site-Registry ueberein.

Loesung: Stellen Sie sicher, dass die exakte Domain (einschliesslich Protokoll) in der Site-Registry-Konfiguration aufgefuehrt ist.

SES sendet keine E-Mails

Ursache: SES befindet sich noch im Sandbox-Modus oder die Sender-Adresse ist nicht verifiziert.

Loesung: Verifizieren Sie die Sender-Domain in SES und beantragen Sie bei Bedarf die Befreiung vom Sandbox-Modus.

Rate-Limiting lehnt alle Anfragen ab

Ursache: DynamoDB-Tabelle wurde nicht korrekt erstellt oder die IAM-Berechtigungen fehlen.

Loesung: Pruefen Sie die CloudWatch-Logs des Lambda fuer Berechtigungsfehler und verifizieren Sie, dass die DynamoDB-Tabelle existiert.

Bounces steigen und SES-Ruf sinkt

Ursache: Sie senden an ungueltige Adressen ohne Unterdrueckung.

Loesung: Stellen Sie sicher, dass der Bounce-Handler korrekt deployed ist und die Unterdrueckungstabelle vor dem E-Mail-Versand geprueft wird.

Zusammenfassung

Sie haben nun ein vollstaendiges serverloses Kontaktformular-Backend, das fuer den Produktionseinsatz bereit ist: Multi-Site-Support mit einer Site-Registry, Schema-validierte Eingaben, DynamoDB-gestuetztes Rate-Limiting mit Fail-Closed-Design, SES-E-Mail-Benachrichtigungen mit Pro-Site-Branding, automatische Bounce-Behandlung zum Schutz Ihres Senderufs, CloudWatch-Monitoring mit Alarmen und ein Frontend-Formular mit Honeypot-Spam-Schutz.

Die haeufigsten naechsten Schritte sind: reCAPTCHA oder Turnstile hinzufuegen fuer staerkere Bot-Praevention, Dateianhang-Support, Webhook-Integration fuer Slack oder Teams-Benachrichtigungen und eine Admin-Oberflaeche zum Anzeigen und Verwalten von Einreichungen.

Das gesamte Projekt ist Open Source und auf GitHub verfuegbar unter serverless-contact-form.