AWS Lambda und API Gateway, Teil 2 Abfrage-API für Amazon Web Services erstellen

Autor / Redakteur: Dipl. -Ing. Thomas Drilling / Stephan Augsten |

Unsere erste Lambda-Funktion haben wir kürzlich erstellt und mit dem eingebauten Test-Framework online getestet. Nun wollen wir eine HTTPS-Rest-API über das Amazon API Gateway programmieren und als Trigger für AWS Lambda verwenden. Dies ist recht komfortabel über die grafische Management Console möglich.

Anbieter zum Thema

Um eine Abfrage-API für Amazon Web Services zu erstellen, verwenden wir in diesem Beitrag die GET-Methode von REST.
Um eine Abfrage-API für Amazon Web Services zu erstellen, verwenden wir in diesem Beitrag die GET-Methode von REST.
(Bild: Drilling / AWS)

Zunächst einmal gilt es, eine neue API zu erstellen.
Zunächst einmal gilt es, eine neue API zu erstellen.
(Bild: Drilling / AWS)

Um einen Trigger für Lambda zu erstellen, wechselt man in der AWS-Management-Console zum Dienst API-Gateway. Er befindet sich im Bereich „Networking & Content Delivery“. Hier erstellen wir mit einem Klick auf „API erstellen“ eine neue API namens „MyHelloAPI“.

Die API Gateway-Console ist derzeit noch nicht vollständig in deutscher Lokalisierung verfügbar. Bei „Choose the protocol“ verwenden wir „REST“, im Abschnitt „Neue API erstellen wählen wir „neue API“ und vergeben im Abschnitt „Einstellungen“ einen API-Namen, eine Beschreibung und wählen beim Endpunkttyp „Regional“.

In der Child-Ressource der definieren wir eine neue Methode vom Typ „Get“.
In der Child-Ressource der definieren wir eine neue Methode vom Typ „Get“.
(Bild: Drilling / AWS)

Ist das geschehen, erstellen wir „innerhalb“ der neuen API mit Hilfe des Menüs „Aktionen / Ressource erstellen“ eine neue Child-Ressource namens „/helloworld“. Auf der neuen Child-Ressource definieren wir dann mit Hilfe des Menüs „Aktionen / Methode erstellen“ eine neue Methode vom Typ „Get“.

Beim Integration-Typ wählen wir „Lambda Function“ und geben dann untern bei „Lambda-Region“ die Region und bei „Lambda Function“ den Namen der im Teil 1 erzeugten Lambda-Funktion ein und klicken auf „Speichern“. Wir bekommen dann den Hinweis, dass wir im Begriff sind, API-Gateway Berechtigungen auf eine Lambda-Funktion einzuräumen.

Detailansicht der GET-Methode.
Detailansicht der GET-Methode.
(Bild: Drilling / AWS)

Das Ergebnis sieht dann so aus, wie in der vorangestellten Abbildung. Man achte auf die visuelle Darstellung der Verarbeitung mit den Pfeilen und dem Client auf der linken Seite sowie der Lambda-Function auf der rechten Seite. Die „Response geht dann zurück über ein JSON-Modell an den Client.

Bevor es weitergehen kann, muss man die API explizit bereitstellen.
Bevor es weitergehen kann, muss man die API explizit bereitstellen.
(Bild: Drilling / AWS)

Bevor wir die das Gateway nutzen können, müssen wir die API allerdings erst „bereitstellen“ (deployen), was in verschiedenen „Stufen“ (Stages) möglich ist. Dazu wählt man im Menü „Actions“ den Eintrag „Deploy API“. Hat man eine Beschreibung und einen Stage festgelegt, erhält man nach kurzer Zeit die fertige „Invoke URL“.

Die Invoke- bzw. Aufruf-URL verweist noch auf Root.
Die Invoke- bzw. Aufruf-URL verweist noch auf Root.
(Bild: Drilling / AWS)

Allerdings verweist die Invoke-URL nur auf das root-Verzeichnis und nicht auf die Child-Ressource, hier “/helloworld“, sodass der Aufruf der Invoke-URL zunächst ein „Missing Authentication Token“ liefert. Mit der richtigen „Sub-URL“ namens „/Test/helloworld“ erscheint dann der richtige Text.

Erst mit der richtigen „Sub-URL“ namens „/Test/helloworld“ erscheint der richtige Text, allerdings mit dem Zusatz „undefined“.
Erst mit der richtigen „Sub-URL“ namens „/Test/helloworld“ erscheint der richtige Text, allerdings mit dem Zusatz „undefined“.
(Bild: Drilling / AWS)

Der „undefined“-Eintrag bedeutet, dann zwar die API funktioniert, wir aber in der Lambda-Funktion noch gar kein echtes Event verarbeiten. Ein echtes Event hat nichts mit dem Test-Event aus dem Workshop in Teil 1 zu tun. Wir haben jetzt zwar die Invoke-URL der neue API aufgerufen, aber noch kein Event übergeben. Hier müssen wie also noch etwas programmieren, wie z.B. einen API-Test.

Wir wechseln daher noch einmal direkt zu API-Gateway-Konsole oder über die Lambda-Konsole zur Get-Methode und passen für diese den „Integration-Request“ an. Das machen wir in diesem Fall bei „Body Mapping Templates“.

HTTP-Daten als Event-Objekt an Lambda übergeben

Hier sind noch ein paar Hintergrundinformationen notwendig: Nach dem Einrichten einer API-Methode muss der Nutzer diese in einen Endpunkt im Backend integrieren. Ein Backend-Endpunkt wird bei AWS APiI Gateway als Integrationsendpunkt bezeichnet. Dabei kann es sich um eine Lambda-Funktion, eine HTTP-Webseite oder eine AWS-Service-Aktion handeln.

Wie bei der API-Methode beinhaltet auch die API-Integration eine „Integrationsanforderung“ (Integration-Request) und eine „Integrationsantwort“ (Integration Response). Die Integrationsanforderung kapselt eine HTTP-Anforderung vom Backend. Diese kann, muss sich aber nicht von der vom Client gesendeten Methodenanforderung unterscheiden. Die Integrationsantwort ist eine HTTP-Antwort, die die Ausgabe des Backends kapselt.

Das Einrichten einer Integrationsanforderung umfasst die folgenden Schritte:

  • Konfiguration, „wie“ die vom Client gesendete Methodenanforderungen an das Backend übergeben werden sollen
  • Konfiguration, „wie“ die Anforderungsdaten gegebenenfalls in die Integrationsanforderungsdaten umgewandelt werden,
  • Festlegen der aufzurufenden Lambda-Funktion,
  • Festlegen des HTTP-Servers, an den die eingehende Anforderung weitergeleitet wird oder Festlegen, welche AWS-Service-Aktion aufgerufen wird.

Da wir eine „Lambda-Funktion“ erstellen, müssen wir dies auch beim Integrationstyp hinterlegen.
Da wir eine „Lambda-Funktion“ erstellen, müssen wir dies auch beim Integrationstyp hinterlegen.
(Bild: Drilling / AWS)

Wir wechseln daher jetzt wieder in die Einstellungen bei „Integrationsanforderung“ und übernehmen als „Integrationstyp“ den Eintrag „Lambda-Funktion“. Hiermit geben wir Informationen zum Ziel-Backend an, das von dieser Methode aufgerufen wird und können ggf. auch angeben, ob die eingehenden Anforderungsdaten dabei verändert werden sollen.

Da wir nicht den Inhalt von URL-Parametern oder HTTP-Headern ausgeben möchten, müssen wir das Pass-Through-Verhalten ändern.
Da wir nicht den Inhalt von URL-Parametern oder HTTP-Headern ausgeben möchten, müssen wir das Pass-Through-Verhalten ändern.
(Bild: Drilling / AWS)

Da wir weder mit URL-Pfadparametern noch mit HTTP-Headern arbeiten wollen, öffnen wir den Knoten bei „Zuweisungsvorlagen“ und klicken dann auf „+ Zuweisungsvorlage“. Hier verwenden wir dann den Typ „application/json“ und bestätigen, dass wie das Pass-Through-Verhalten ändern möchten.

Im zweiten Schritt des Pass-Through-Verhaltens erzeugen wir ein JSON-Template.
Im zweiten Schritt des Pass-Through-Verhaltens erzeugen wir ein JSON-Template.
(Bild: Drilling / AWS)

Danach kann man unten bei „Vorlage erzeugen“ ein passendes Template im JSON-Format schreiben, etwa folgendermaßen:

{
   „key1“ : „$input.params(‘key1‘)“
}

Hierzu ebenfalls ein paar Hintergrundinfos: Eine Integrationsanforderung ist eine HTTP-Anforderung, die das API Gateway ans Backend sendet und dabei die vom Client gesendeten Anforderungsdaten übergibt. Diese lassen sich (bei Bedarf) während der Übergabe den abgebildeten Optionen gemäß umwandeln. Die HTTP-Methode (oder Verb) und URI der Integrationsanforderung werden vom Backend, also dem Integrationsendpunkt, vorgegeben. Diese können, müssen aber nicht mit der HTTP-Methode und URI der Methodenanforderung übereinstimmen.

Gibt etwa eine Lambda-Funktion eine Datei zurück, die aus Amazon S3 abgerufen wurde, kann der Nutzer diesen Vorgang intuitiv als GET-Methodenanforderung an den Client festlegen, obwohl für die entsprechende Integrationsanforderung eine POST-Anforderung verwendet werden muss, um die Lambda-Funktion aufzurufen. Bei einem HTTP-Endpunkt ist es dagegen eher wahrscheinlich, dass für die Methodenanforderung und die entsprechende Integrationsanforderung dasselbe HTTP-Verb verwendet wird. Dies ist jedoch nicht erforderlich.

Die API-Gateway-Dokumentation verrät, welche Methodenanforderung integrierbar sind: Bei der von uns verwendeten Zuweisungsvorlage „application/json“ handelt es sich um ein Script in der Velocity Template Language (VTL), das mithilfe von JSONPath-Ausdrücken auf die Nutzlast angewendet wird.

Der Payload kann ein dem JSON-Schema Entwurf 4 entsprechendes Datenmodell umfassen. Der Nutzer muss dieses Modell definieren, um es API Gateway zu ermöglichen, ein SDK zu erzeugen oder um die grundlegende Anforderungsvalidierung für Ihre API zu aktivieren.

Aber Achtung: Der Anwender muss nicht zwingend ein Modell definieren, um eine Zuweisungsvorlage zu erstellen. Ein solches kann aber beim Erstellen einer Vorlage hilfreich sein, da API Gateway einen Vorlagenplan auf Basis des bereitgestellten Modells erzeugt.

Das erneute Bereitstellen der API kann später im Prod-Stage erfolgen.
Das erneute Bereitstellen der API kann später im Prod-Stage erfolgen.
(Bild: Drilling / AWS)

In jedem Fall müssen wir unsere API mit dieser Änderung nun wieder neu bereitstellen; diesmal verwenden wir den Prod-Stage. Damit erhalten wir nach Aufruf der Invoke-URL nun kein „undefined“ mehr. Außerdem sind wir jetzt in der Lage, das gewünschte Event per HTTP-Get-Methode in der URL zu übergeben. Wir übergeben nun also wieder die Zeichenfolge „Hallo Welt“ mittels:

[URL]?key1=HalloWelt:

Das gewünschte Event lässt sich nun per HTTP-Get-Methode in der URL übergeben.
Das gewünschte Event lässt sich nun per HTTP-Get-Methode in der URL übergeben.
(Bild: Drilling / AWS)

Im nächsten Teil kümmern wir uns darum, API-Zugriffe mit einem API-Schlüssel zu schützen bzw. privat zu machen. Darüber hinaus betrachten wir, wie sich das Testen von APIs mit entsprechenden Tools komfortabler gestalten lässt.

(ID:45863125)