APIs in JavaScript verwenden (2/2)
Im ersten Teil dieses Tutorials haben wir gezeigt, wie man eine Oberfläche für einen Übersetzer in HTML und CSS entwickelt. Im zweiten Teil geht es nun darum, wie die notwendige Funktionalität mit reinem JavaScript implementiert werden kann.
Eine API anbinden
Wir werden in diesem Tutorial keinen Algorithmus schreiben, der einen Text übersetzen kann. Stattdessen werden wir eine API nutzen, die uns eine solche Funktion zur Verfügung stellt. Eine API (Application Programming Interface) ist eine Schnittstelle, mit der ein Programm an ein anderes Programm oder System angebunden werden kann. Dazu definiert das System, das die API zur Verfügung stellt, welche Eingaben erwartet und welche Werte herausgegeben werden. Was allerdings hinter der Schnittstelle passiert, bleibt verborgen. Es gibt Schnittstellen von verschiedenen Softwareherstellern und auch von Softwareriesen wie Google oder Twitter, die Zugang zu sehr unterschiedlichen Daten und Funktionalitäten liefern.
Meistens gehen mit der Nutzung einer API bestimmte Bedingungen einher, beispielsweise Kosten oder die Verpflichtung, einen Link zur API im Programm oder auf der Webseite anzuzeigen. Insbesondere für kommerzielle Anwendungen müssen diese Richtlinien beachtet werden, da es sonst zu rechtlichen Konsequenzen kommen kann.
Yandex ist eine API für Übersetzungen, die wir für unsere Webseite verwenden werden. Um Anfragen an Yandex schicken zu können, benötigen Sie einen API Key, den Sie über einen kostenlosen Account erhalten. Dieser Key dient zur Identifizierung Ihrer Applikation. Um einen Key zu erhalten, melden Sie sich bei Yandex an. Wenn Sie sich einloggen, werden Sie direkt auf die Seite API Keys weitergeleitet. Klicken Sie auf Create a new key und geben Sie einen Anwendungszweck an. Nun erhalten Sie einen recht langen Schlüssel, den Sie für Anfragen verwenden können.
Yandex schreibt vor, dass der Text Powered by Yandex.Translate bei dem Ergebnis der Übersetzung zu sehen sein muss. Fügen wir diesen Hinweis direkt in das HTML in einer eigenen Spalte ein:
Machen Sie sich anschließend selbst mit der Yandex API Documentation vertraut. Wir werden zwei Funktionen benötigen: Zum einen das Abfragen aller verfügbaren Sprachen, zum anderen das Übersetzen eines Wortes oder Ausdrucks selbst.
Um das Skript zu implementieren, erstellen Sie neben dem css-Ordner noch einen js-Ordner und legen eine Datei script.js an. Binden Sie die Datei im HTML ein:
Als Erstes werden wir alle Sprachen, die Yandex zur Verfügung stellt, abfragen, um damit die select-Elemente zu befüllen. Um Webanfragen zu stellen, gibt es in JavaScript einige Bibliotheken, beispielsweise jQuery. Wir werden die Requests allerdings selbst auf Basis der Klasse XMLHttpRequest erstellen, um nicht von einer Fremdbibliothek abzuhängen. XMLHttpRequest ist eine durch die W3C standardisierte Klasse, mit der Daten von URLs abgerufen werden können. Die Dokumente können ein beliebiges Format haben, auch wenn der Klassenname die Vermutung nahelegt, man müsse sich an das XML-Format halten.
Um eine Anfrage zu verschicken, wird folgender Code benötigt:
In diesem Codeausschnitt wird zuerst ein Objekt vom Typ XMLHttpRequest erstellt. Um auf eine Antwort auf das Request zu reagieren, wird eine anonyme Funktion für die Eigenschaft onreadystatechange des Objektes definiert. Ändert sich der ReadyState, wird die Funktion ausgeführt. Für den Fall, dass die Anfrage erfolgreich war, wird das Ergebnis verarbeitet. Eine Anfrage ist erfolgreich, wenn ihr HTTP-Code 200 OK und ihr ReadyState 4 DONE ist. Für andere Fälle könnte an dieser Stelle eine Fehlerbehandlung implementiert werden.
Die Funktion open initialisiert anschließend die Anfrage mit einem Anfragetyp (z.B. GET, POST, DELETE), einer URL, einem optionalen Parameter, der angibt, ob die Anfrage synchron oder asynchron ist, und zwei optionalen Parametern für Nutzername und Passwort. Ist der Request asynchron, bedeutet das, dass die weitere Abarbeitung des Programms nach dem Absenden der Anfrage nicht auf eine Antwort wartet. Nutzername und Passwort sind an dieser Stelle nicht notwendig, da der API Key in der URL geschickt wird. Zuletzt wir das Request mit der Methode send() versendet.
Schreiben wir mit diesem Code eine Funktion initLanguageSelect(), die zuerst nur den Inhalt des erfolgreichen Requests loggt. Die URL, zu der die Anfrage gesendet wird, ist https://translate.yandex.net/api/v1.5/tr.json/getLangs?key=&ui=en.
Der Parameter key entspricht Ihrem API Key, der Parameter ui ist optional und gibt die gewünschte Anzeigesprache des Response an.
Rufen Sie die Funktion auf, wenn der Body des Dokuments geladen wird, damit die select-Elemente direkt befüllt werden.
<body onload="initLanguages">
Sobald der Body des Dokuments geladen wird, wird nun die Funktion aus dem Skript aufgerufen. Um den Inhalt des Response zu sehen, öffnen Sie die Webseite in Ihrem Browser und starten anschließend den Inspektor, indem Sie mit Rechtsklick das Kontextmenü öffnen und Untersuchen wählen.
Im Inspektor können Sie das HTML, die Netzwerkaktivität oder die Ausgabe der Webseite einsehen. Den Inspektor gibt es in jedem modernen Webbrowser, in diesem Tutorial wird Chrome verwendet.
Öffnen Sie das Tab Console. Sie sollten dort folgende Ausgabe sehen:
Das ist der Inhalt des Response, den wir mit
console.log(this.reponseText);
geloggt haben. Die Ausgabe ist im Json (JavaScript Object Notation)-Format. Dieses Format speichert Daten als Schlüssel-Wert-Paare, um damit komplexe Datenstrukturen zu repräsentieren. Auf einzelne Werte können Sie über den Array-Element-Operator [] zugreifen.
JavaScript bietet out-of-the-box-Funktionen an, mit denen Sie zwischen Json-Objekten und Strings konvertieren können:
- JSON.parse(String), um aus einem String ein Json-Objekt zu machen
- JSON.stringify(Object), um aus einem Objekt einen validen Json-String zu erzeugen
Parsen Sie also das Objekt und geben den Inhalt des Keys langs aus:
var languages = JSON.parse(this.responseText)["langs"];
console.log(languages);
Aktualisieren Sie den Browser. Dadurch leert sich die Konsole und die neue Ausgabe erscheint.
Nun müssen wir aus dieser Liste an Schlüssel-Wert-Paaren Optionen für die select-Elemente erstellen. Die Optionen für ein select-Element haben folgende Syntax:
<option value="value">Displayname</option>
Schreiben wir also zuerst eine Funktion, die einen Wert und einen Anzeigenamen entgegennimmt und daraus ein option-Element erzeugt:
Wir nutzen dazu die Funktion createElement, die uns ein beliebiges Element auf unserem Dokument erzeugt. Die so erzeugte Option erhält den übergeben Text und Value. Am Ende gibt die Methode das Element einfach zur weiteren Verwendung zurück.
In der Methode initLanguageSelect() greifen wir nun auf die beiden Select-Felder zu:
Anschließend iterieren wir über die einzelnen Schlüssel aus der Liste aller Sprachen und rufen die Methode createOption für jede Sprache auf. Das so erzeugte Element fügen wir den select-Elementen mittels der Funktion appendChild hinzu:
Zum Ende der Methode setzen wir noch den Default-Wert für die Ausgangssprache auf de und den Zielwert auf en.
sourceLanguageSelect.value="de";
targetLanguageSelect.value="en";
Insgesamt sieht die Funktion nun so aus:
Sie können das console.log entfernen, da wir die Ausgabe nun nicht mehr benötigen.
Aktualisieren Sie die Seite im Browser – zu Beginn sollten nun beide Selektionselemente befüllt sein.
Text übersetzen
Zuletzt benötigen wir nun die Anbindung an die Übersetzer API von Yandex. Schreiben Sie eine Funktion translateText(). Diese muss Folgendes tun:
- Eingabewerte aus dem Dokument auslesen
- Die Anfrage zusammenbauen und an Yandex schicken
- Die Übersetzung aus der Antwort extrahieren und in das Ausgabefeld schreiben
Yandex gibt uns eine klar definierte Schnittstelle unter der URL https://translate.yandex.net/api/v1.5/tr.json/translate vor. Diese erwartet folgende Parameter:
- key: Ihr API-Key
- text: Der zu übersetzende Text
- lang: Die Sprachcodes der Eingabe- und Ausgabesprache, durch einen Bindestrich getrennt
Lesen wir die benötigen Werte aus dem Dokument aus:
Mit diesen Informationen können wir nun zuerst die URL bauen und anschließend ein neues XMLHttpRequest-Objekt erzeugen. Mit diesem loggen wir wieder nur den responseText, damit wir ihn genauer inspizieren können.
Verknüpfen Sie die Funktion mit dem Translate-Button über das Attribut onclick:
<button type="button" id="translate_button" onclick="translateText()">Translate</button>
Aktualisieren Sie den Browser, machen Sie eine Eingabe (beispielsweise Katze) und klicken Sie Translate. Sie sollten nun folgende Ausgabe in der Konsole sehen.
Damit der Wert Cat auf der Oberfläche angezeigt wird, müssen wir also den reponseText wieder in ein JSON-Objekt umwandeln, und den Inhalt des Keys text in das Ausgabefeld schreiben. Beachten Sie, dass es sich um eine Liste an möglichen Übersetzungen handelt.
document.getElementById("translated_text").value = JSON.parse(this.responseText)["text"][0];
Insgesamt sieht die Funktion zum Übersetzen nun so aus:
Testen Sie, ob die Eingabe funktioniert und das Ergebnis der Anfrage im Ausgabefeld erscheint.
Damit ist der Übersetzer in seiner Grundfunktionalität abgeschlossen. Wenn Sie an diesem Projekt noch weiter arbeiten wollen, können Sie beispielsweise eine Historie über die letzten Anfragen einbauen oder auch mehrere mögliche Übersetzungen, anstatt nur der ersten, im Ausgabefeld anzeigen.