fetch: Daten aus dem Web
Dauer: ca. 45 Minuten
- JavaScript im Browser hat eine
fetch-Funktion für Web-Daten node-fetchstellt diese in Node.js bereit (ab Node.js 18 nativ!)fetchist asynchron und liefert Promisesasync/awaitvereinfacht den Umgang mit Promises
Ziel: Daten von Webservice-APIs einbinden
Am Beispiel des Wetterdienstes Open-Meteo wollen wir die aktuelle Temperatur für Berlin abfragen.
Die kostenlose und frei zugängliche API (application programming interface) von Open-Meteo kann dazu mit folgender URL (Web-Link) angefragt werden:
https://api.open-meteo.com/v1/forecast?latitude=52.52&longitude=13.41¤t_weather=trueDie Koordinaten für Berlin (Breitengrad 52.51, Längengrad 13.41) werden als Parameter in der URL übermittelt, sodass der Server die gewünschte Anfrage ausführen und das Ergebnis als JSON-Daten liefern kann.
Im Browser steht JavaScript eine Funktion
fetch zur Verfügung, mit der Daten aus dem Web
via URL z.B. als JSON angefordert werden können.
⟶ URL im Browser laden und fetch mit
open-meteo.com in der Browser-Konsole vorführen.
fetch verwenden
Nun kann fetch in replit.com bzw. Node.js
wie im Browser verwendet werden.
Da ein Netzwerkzugriff mit fetch unter
Umständen etwas länger dauern kann (z.B.
bei langsamer Internetverbindung), läuft
fetch asynchron bzw. „im Hintergrund“ ab.
Das Ergebnis von fetch ist daher ein
Promise-Objekt, das mit Callback-Funktionen
asynchron verarbeitet werden muss.
Promises
stellen ein etwas schwer zugängliches Thema in
JavaScript dar. Für die Verwendung von fetch
besprechen wir hier nur das Nötigste.
Die Verwendung von fetch und Promises läuft
folgendermaßen ab:
fetchmit URL aufrufen, dies liefert ein Promise-Objekt- das Promise-Objekt enthält eine
response, die mit der Methodejson()die JSON-Daten liefert responseim Promise-Objekt kann mitthenausgelesen werden — hierbei wird ein Callback inthenbenötigtthenliefert wieder ein Promise-Objekt, das das JavaScript-Objekt basierend auf den JSON-Daten enthält- dieses kann wiederum mit
thenund Callback-Funktion verarbeitet werden
Der Code in der Funktion
getBerlinWeatherPromiseSteps() zeigt,
wie dies umgesetzt wird:
function getBerlinWeatherPromiseSteps() {
const url =
`https://api.open-meteo.com/v1/forecast?latitude=52.52&longitude=13.41¤t_weather=true`;
// 1. Schritt: fetch ausführen
// --> Das Ergebnis ist ein Promise-Objekt
const fetchPromise = fetch(url);
// 2. Schritt: aus dem fetchPromise die
// JSON-Daten durch response.json() mit Callback in then() auslesen
// --> then liefert wieder ein Promise-Objekt
const dataPromise =
fetchPromise.then(response => response.json());
// 3. Schritt: aus dem dataPromise die relevanten Daten mit then() ausgeben
dataPromise.then(data => console.log(data.current_weather.temperature));
}Da die einzelnen Aufrufe von then wiederum
Promises liefern, können diese direkt
miteinander kombiniert werden (dies wird
„chaining“ genannt):
function getBerlinWeatherPromiseChained() {
const url =
`https://api.open-meteo.com/v1/forecast?latitude=52.52&longitude=13.41¤t_weather=true`;
fetch(url)
.then(response => response.json())
.then(data => console.log(data.current_weather.temperature));
}Somit ist die Verwendung von fetch bereits
einigermaßen kompakt und übersichtlich
möglich.
Promises mit then kann schnell zu
unübersichtlichem Code führen. Alternativ kann
async/await zum Einsatz kommen.
async/await für Promises
Mit async/awaitwird die Verarbeitung von
Promises leichter nachvollziehbarer.
Der Code der obigen Funktionen kann ebenso
mit async/await ausgedrückt werden.
Dazu ist eine Funktion mit dem Schlüsselwort
async vor function zu deklarieren:
// Die Funktion ist nun asynchron!
async function getBerlinWeatherAwait() {
const url =
`https://api.open-meteo.com/v1/forecast?latitude=52.52&longitude=13.41¤t_weather=true`;
const response = await fetch(url);
const data = await response.json();
console.log(data.current_weather.temperature);
return data.current_weather.temperature;
}await löst einen Promise auf und liefert
das Ergebnis zurück. Gleichzeitig „wartet“
(await) der Code auf die Verarbeitung, sodass
der Code einem „normalem“ synchronen Ablauf
syntaktisch ähnelt.
⟶ await ist nur dann in einer Funktion erlaubt,
wenn diese mit async deklariert wurde!
Der Rückgabewert einer async-Funktion ist
wiederum ein Promise, der automatisch von
JavaScript erzeugt wird. Um den „eigentlichen“
Rückgabewert im Promise einer async-Funktion
zu verwenden, muss dieser mit await in einer
weiteren async-Funktion angefragt werden:
async function berlinTemperature() {
const temp = await getBerlinWeatherAwait();
console.log("Temperatur in Berlin: " + temp);
}
berlinTemperature();Beim Zugriff auf APIs bzw. Webservices mit fetch können
verschiedene Fehlersituationen eintreten:
- keine Internetverbindung,
- Server ist nicht erreichbar,
- Antwort des Servers passt nicht zum erwarteten Ergebnis,
- u.a.
Daher sollte ein Webzugriff mit fetch z.B. mit
try…catch-Blöcken umgeben werden, um
Fehlersituationen im Code zu behandeln.
Dieser Artikel beschreibt ausführlich, was bei der Verwendung von fetch
zu beachten ist, und zeigt praktische Code-Beispiele:
www.builder.io/blog/safe-data-fetching