7. Persistenz, Autorisierung, Cookies
7.7 Web-APIs von Drittanbietern verwenden
Konzeptuell wird dieses Kapitel nichts wirklich Neues einführen. Ziel ist es, ein Mini-Frontend zu bauen, das eine "echte" Web-API verwendet. Als Beispiel habe ich hierfür GeoDB gewählt. Dies ist eine API, über die Sie sich z.B. Listen von Städten holen können.
Authorisierung Für viele APIs müssen Sie sich authorisieren, und bei intensiver oder kommerzieller Nutzung auch: beazahlen! Bei RapidApi können Sie sich einen Nutzer-Account anlegen und dann bei GeoDB die "Basic Subscription" für $0.00 im Monat wählen. Die Funktionalität der API ist dann zwar beschränkt, für unsere Lernzwecke reicht es allerdings.
Sie erhalten dann einen API-Key, mit dem Sie sich bei jedem Request authorisieren müssen. Der Browser (oder wer auch immer die Requests an die GeoDB-Api tätigt), muss in jedem Request den API-Key mitsenden. Wie wird dieser übermittelt?
- Bei RapidAPI wird im Http-Header die Zele
X-RapidAPI-Key: g4br8vfw7v7nrepfomxv
gesetzt (kein echter Schlüssel hier sondern Zufallsstring). - Bei AccuWeather wird der
API-Key direkt als Query-Parameter in der URL angegeben:
http://dataservice.accuweather.com/locations/v1/regions?apikey=g4br8vfw7v7nrepfomxv
- Cookies können im Allgemeinen wohl nicht verwendet werden: der Browser schickt die bei CORS-Requests normalerweise nicht mit. Würde er dies tun, entstünden tausend Sicherheitslücken.
Methode 2 ist etwas unsicherer als Methode 1: wenn der Key direkt in der URL drinsteht, ist er für jedermann sichtbar, kann in Bookmarks gespeichert (und während der Raucherpause vom bösen Bürokollegen gelesen) werden. Allerdings ist es für Lernzwecke schön, weil man dann die API-Requests einfach über die Adresszeile eingeben kann; mit Methode 1 geht das nicht, da müssen Sie immer den Header setzen, was mit Ajax einfach geht, aber eben nicht per Browser-Adresszeile.
Übungsaufgabe Legen Sie einen RapidAPI-Zugang an, abbonieren GeoDB für $0.00 im Monat und speichern Sie sich Ihren API-Key.
Gehen Sie auf GeoDB
Cities,
der Spezifikation für den Endpoint
https://wft-geo-db.p.rapidapi.com/v1/geo/cities
.
Lesen Sie sich durch, welche Parameter ("Optional Parameters") der
Query-String beinhalten kann.
Lesen Sie sich das JSON-Format durch. So lernen Sie das Format kennen, in welchem die GeoDB-API unsere Anfragen beantwortet. Schauen Sie nun in den Quelltext von geodb-cityname.html und speichern sich die Seite lokal auf Ihrem Rechner.
Übungsaufgabe
Ändern Sie die Seite so, dass man sich Surchgebnisse \(n+1 \dots n+10\) zeigen lassen kann.
Hinweis: achten Sie auf den Query-Parameter offset
.
Übungsaufgabe
Fügen Sie Ihrer Seite Links bzw. Knöpfe prev
und next
hinzu,
mit denen man sich die vorherigen 10 bzw. nächsten 10 Treffer anzeigen lassen kann.
Übungsaufgabe Ändern Sie Ihre Seite: die Suchergebnisse sollen nicht mehr roh als JSON angezeigt werden, sondern schön als Tabelle mit folgenden Spalten: Name, (Breitengrad, Längengrad), Einwohnerzahl
Übungsaufgabe
Erweitern Sie Ihre Seite: beim Klick auf eine Stadt soll
die lokale Zeit angezeigt werden. Hierfür brauchen Sie den Endpoint
/v1/geo/cities/{CITYID}/dateTime
. Die Referenz
dafür finden Sie auf
GeoDB Cities
unter dem Punkt City Date-Time.
Übungsaufgabe Legen Sie auf AccuWeather einen Zugang an und machen sich mit der API vertraut. Schreiben Sie ein Frontend, auf dem der User den Namen einer Stadt eingeben soll. Daraufhin soll eine Tabelle erstellt werden, die alle Städte mit diesem Namen auflistet und für jede die folgenden Daten darstellt:
- Geographische Lage (Breitengrad, Längengrad, Höhe über dem Meeresspiegel),
- Tagestiefst- und Tageshöchsttemperatur.
Hierfür brauchen Sie zwei Endpoints:
Im Frontend versus im Backend
Der Nachteil aller Apps, die wir in diesem Teilkapitel geschrieben haben, war, dass entweder der Nutzer den API-Key haben und eingeben muss oder wir als Entwickler ihn hart in den Code unserer Seite einbinden müssen. Letzteres ist natürlich schlecht, denn dann ist er ja allen öffentlich zugänglich. Verlagern wir nun die Kommunikation mit dem der API in ein Backend.
Übungsaufgabe
Schreiben Sie einen Server, der
die beiden Endpoints /get-cities-by-prefix
und /get-local-time
anbietet und dann die Anfrage
an die GeoDB-API weiterleitet und den Response an die Webseite des Nutzers.
Am Frontend müssen Sie fast nichts ändern, nur der URLs Ihrer Ajax-Requests müssen
Sie anpassen.
Hierzu müssen Sie wissen, wie man in Node.js einen HTTP-Request erstellt und
behandelt. Ich verwende für diese Vorlesung das Paket axios
.
Sie können sich an dem Endpoint "/get-cities"
in server.js
in 13-login-server.zip
orientieren (das ist neu; Sie müssen die zip-Datei also eventuell erneut herunterladen).
Alternativ hier der Code zur Orientierung:
const axios = require('axios');
app.get("/get-cities", async function (req, res) {
const query = url.parse(req.url, true).query;
let n = parseInt(query.n) || 0;
let result = { result: fib(n) };
const options = {
method: 'GET',
url: 'https://wft-geo-db.p.rapidapi.com/v1/geo/cities',
headers: {
'X-RapidAPI-Key': '3004920d14msh6d79ab4e117d68ep130870jsn456d0c3abdd6',
'X-RapidAPI-Host': 'wft-geo-db.p.rapidapi.com'
},
params: { limit: 2, namePrefix: "Berli", offset: 30 }
};
try {
const response = await axios.request(options);
console.log(response.data);
res.send(JSON.stringify(response.data));
} catch (error) {
console.log("http request to wft-geo-db has failed");
return res.send("http request to wft-geo-db has failed");
}
});