Mit den CloudFront Functions bietet AWS die Möglichkeit, den Funktionsumfang von CloudFront um kleine JavaScript-Funktionen zu erweitern. AWS führt diese Funktionen direkt an den Edge-Locations aus und ermöglicht es dadurch, alle ankommenden Requests auszuwerten oder zu bearbeiten, bevor sie an die Backend-Systeme weitergesendet werden.
Das folgende Beispiel zeigt eine einfache CloudFront Function, die einen ankommenden Request als event
übergeben bekommt. Diesem Request wird ein Header hinzugefügt, bevor der Request zur weiteren Verarbeitung wieder an CloudFront übergeben wird.
1function handler(event) {
2 const request = event.request;
3 request.headers['custom-header'] = { value: "some value"};
4 return request;
5}
Da die Funktionen für jeden Request ausgeführt werden, ist es besonders wichtig, dass die Ausführung performant und effizient erfolgt. Ein Grund dafür, dass die CloudFront Functions so performant sind, ist der reduzierte JavaScript-Funktionsumfang. Es sind hauptsächlich ES5- und ausgewählte ES6- und ES7-Features verfügbar. Damit fallen auch import
- und export
-Statements weg, die genutzt werden, um Code als Node-Module in anderen Dateien wiederzuverwenden.
1// module.js
2export function myExportedFunction(event) {...}
3
4// Im Test kann die exportierte Funktion kann nach dem Import genutzt werden
5import { myExportedFunction } from './module.js';
Für die Anbindung der Funktion an CloudFront ist der fehlende export
kein Problem, da lediglich der Pfad zur JavaScript-Datei benötigt wird. Wenn wir die Funktion aber mit Unit-Tests absichern wollen, stoßen wir auf Probleme. Amazon bietet zwar die Möglichkeit, CloudFront Functions manuell in der AWS-Konsole zu testen. Dies kann automatisierte Tests allerdings nicht ersetzen.
Im Folgenden beschreibe ich zwei Möglichkeiten, die es ermöglichen, unsere CloudFront Functions zu testen, auch wenn wir sie nicht als Node-Module exportieren können.
Lösung 1: Function
Die JavaScript-Funktion readFileSync
erlaubt es, Dateien einzulesen und im JavaScript-Code zu nutzen. Anschließend lässt sich der eingelesene Code über den Function
-Konstruktor initialisieren. Wir können jetzt unsere Tests wie gewohnt schreiben.
1const code = fs.readFileSync('./cloudfront-function.js'); 2const handler = new Function(`return ${code.toString()}`)(); 3 4// Die Funktion im Folgenden getestet werden 5const result = handler(event);
Der Vorteil dieser Lösung ist, dass sie ausschließlich JavaScript-Features nutzt. Es ist also keine zusätzliche Dependency notwendig. Auf der anderen Seite müssen wir etwas mehr Code schreiben, um die Datei zu lesen und als Funktion zu initialisieren. Eine Alternative zum Function
-Konstruktor ist die eval-Funktion, die ebenfalls JavaScript-Code aus einem String parsen kann.
⚠️ Achtung! Beide Lösungen sind mit Vorsicht zu genießen. Das Einlesen von Code aus externen Quellen stellt ein Sicherheitsrisiko dar und sollte nur in einem gesicherten Umfeld stattfinden. In unserem Fall werden die Funktionen aber nur in Tests genutzt und öffnen keine Schwachstellen in unserem Produktivcode.
Lösung 2: rewire
Die Bibliothek rewire erlaubt es, auf nicht-exportierte Properties und Funktionen zuzugreifen. Diese können entweder mit __get__
gelesen oder mit __set__
geschrieben werden. In unserem Fall reicht die Get-Funktion, der wir den Namen der gesuchten Funktion übergeben. Die Bibliothek gibt uns dann Zugriff auf die eigentlich nicht exportierte Funktion.
1const handler = rewire('./extract-ids-from-path.js').__get__('handler');
Im Vergleich zur ersten Lösung können wir hier also mit weniger Code an die zu testende Funktion kommen. Dafür müssen wir aber eine zusätzliche Dependency zu unserem Projekt hinzufügen.
Fazit
Auch wenn es auf den ersten Blick ungewohnt ist, gibt es verschiedene Ansätze, um unsere CloudFront Functions zu testen. Je nach Präferenz können wir ausschließlich JavaScript nutzen oder eine zusätzliche Dependency hinzufügen, um etwas Code sparen. Egal für welchen Weg wir uns entscheiden: Unser Code sollte automatisiert getestet werden, um nicht auf manuelle Tests über die AWS-Konsole angewiesen zu sein.
Weitere Beiträge
von Dennis
Dein Job bei codecentric?
Jobs
Agile Developer und Consultant (w/d/m)
Alle Standorte
Weitere Artikel in diesem Themenbereich
Entdecke spannende weiterführende Themen und lass dich von der codecentric Welt inspirieren.
Gemeinsam bessere Projekte umsetzen.
Wir helfen deinem Unternehmen.
Du stehst vor einer großen IT-Herausforderung? Wir sorgen für eine maßgeschneiderte Unterstützung. Informiere dich jetzt.
Hilf uns, noch besser zu werden.
Wir sind immer auf der Suche nach neuen Talenten. Auch für dich ist die passende Stelle dabei.
Blog-Autor*in
Dennis
IT Consultant
Du hast noch Fragen zu diesem Thema? Dann sprich mich einfach an.
Du hast noch Fragen zu diesem Thema? Dann sprich mich einfach an.