ursus contionabundo: Beispiel für API Schnittstelle

Beitrag lesen

Ah. So allgemeine Informationen wolltest Du.

Also, die "API-Geschichte" läuft auf folgendes hinaus:

Einerseits hast Du einen Server, der - hier via http[s] Informationen oder Aktionen feilbietet wenn man ihm nur richtig fragt. Andererseits einen Client. Ein solcher Client kann ein Browser (in diesem Javascript) sein, aber auch eine Software, z.B. ein PHP-Skript oder halt jedes andere Programm. Einziger Bedingung: In Falle einer Web-API (Man kann sowas auch mit ssh oder telnet "stricken", scheitert dann aber gerne an Firewalls) muss es http[s]-Requests senden und auswerten können.

Der Trick ist also, dass ein Programm mit einem Server kommuniziert. Bei HTTP gehören zu diesem "richtig fragt" folgende Informationen:

  • die im Header hinterlegte Methode. Kandidaten sind GET, POST aber auch auch PATCH und DELETE.
  • die URL selbst, damit also verbunden die Request-Daten.
  • POST-Daten, die auch mit dem HTTP-Header gesendet werden.
  • Freilich lässt sich auch alles bis zu x-headern (das 'x-' zeigt an, dass der Header nicht genormt ist, vom Webserver (wenn nicht für ihn bestimmt) zumeist ignoriert aber CGI-Anwendungen (wie PHP) oder Modulen (wie eben auch PHP) mitgeteilt wird.

Also bekommt der Server eine Anfrage und wird darauf hin hoffentlich antworten.

Diese Antwort setzt sich zusammen aus dem HTTP-Header und dem Payload. Payload kennt man z.B. als Webseite. In Falle einer API wird das am häufigsten Text sein, der allerdings - eben so wie anderer Payload komprimiert gesendet werden und gecached werden darf - wie eben eine Webseite auch. Ebenso wird der Server weitere Informationen wie den HTTPS-Status (404 Not Found, 403 Forbidden, 301 Moved Permanently, 500 Internal Error, …) übertragen.

Der Text aus dem Payload wiederum kann - je nach Lust, Laune, Erfordernissen oder betrieblicher Übung als JSON, XML, CSV oder auch in einem proprietären Format formuliert sein. Serverseitig ist regelmäßig Programm, z.B. ein PHP-Skript für die Erzeugung zuständig. Genau wie man das von normalen webseiten kennt.

Es folgt die Praxis an Hand dieses simplen Beispiels mit GET.

Der Server sendet entsprechend der zwischen meinereinerselbst und meiner Wenigkeit getroffenen Vereinbarung nach einem Abruf der nachfolgenden URL je nach Betriebszustand folgendes JSON, dessen innere Struktur auch zwischen meiner Wenigkeit und meinereinerselbst vereinbart wurde:

https://home.fastix.org/Tests/sysview.api.php?q=TEMP_BANANA_PI,UPTIME,LOAD

{
    "TEMP_BANANA_PI": {
        "dataType": "ARRAY",
        "data": {
            "VALUE": "35.4",
            "STRING": "35.4°C",
            "WARN_MAX_VALUE": 85,
            "WARN_MAX_STRING": "85°C",
            "WARN_MIN_VALUE": 10,
            "WARN_MIN_STRING": "10°C",
            "DEAD_VALUE": 90,
            "DEAD_STRING": "90°C",
            "CPUFREQ_VALUE": "600000",
            "CPUFREQ_STRING": "0,60 GHz"
        }
    },
    "UPTIME": {
        "dataType": "ARRAY",
        "data": {
            "Sekunden absolut": 1541237,
            "Tage": 17,
            "Stunden": 20,
            "Minuten": 7,
            "Sekunden": 17,
            "STRING": "17d 20:07:17"
        }
    },
    "LOAD": {
        "dataType": "ARRAY",
        "data": {
            "s": "0.00 0.00 0.00 1\/115 25138",
            "avg1min": "0.00",
            "avg5min": "0.00",
            "avg15min": "0.00",
            "Prozessoren": 4,
            "Last": {
                "cpu0": "0.8%",
                "cpu1": "0.9%",
                "cpu2": "0.9%",
                "cpu3": "0.9%",
                "Gesamt": "0.9%"
            }
        }
    }
}

Man kann das mit Javascript auswerten, wie das in diesem einfachen Fall geht siehst Du hier im Quelltext.

Du willst aber etwas anderes, bei Dir ist PHP der Client.

Anders als dedlfix würde ich würde ich dazu neigen, gleich die curl-Funktionen von PHP zu benutzen. Freilich kann es sein, dass wenige, einzelne Hoster diese nicht installiert oder (warum auch man immer jemand sowas tut) zwar installiert aber in der PHP.ini blockiert haben:

<?php
 // erzeuge einen neuen cURL-Handle
 $ch = curl_init();

 // setze die URL und andere Optionen
 $dummy = curl_setopt( $ch, CURLOPT_URL, "https://home.fastix.org/Tests/sysview.api.php?q=TEMP_BANANA_PI,UPTIME,LOAD" );
 $dummy = curl_setopt( $ch, CURLOPT_HEADER, 0 );
 // Muss gesetzt werden, damit der Payload in die Variable geschrieben werden kann - Sonst erfolgt Ausgabe von 1 (Erfolg) oder 0 (Fehler).
 $dummy = curl_setopt( $ch, CURLOPT_RETURNTRANSFER, 1 );

 // führe die Aktion aus und gib die Daten an den Browser weiter
 $result = curl_exec( $ch );

 // Der Einfachheit halber decodiere JSON und gebe die Daten aus:
 header('Content-Type: text/plain; charset=utf-8');
 echo "==============================================================\n";
 echo "EMPFANGENE DATEN:\n";
 echo "==============================================================\n";
 print_r (json_decode( $result ) );
 echo "==============================================================\n";
 // schließe den cURL-Handle und gib die Systemresourcen frei
 $dummy = curl_close( $ch );

Abruf dieses Tests.

Warum curl?

curl kann Post-Daten, HTTP-Methode, HTTP-Header manipulieren und, ähnlich wie der "xmlHttpRequest" auch auswerten. Die anderen Methoden insbesondere die eigentlich zum Öffnen von Dateien gedachten, stehen da hinten an. APIs (insbesondere von dritten) sind "lebende Standards" - ändern sich also manchmal. Und dann von einem "Dateiöffner" auf Curl umzusteigen (weil der Anbieter plötzlich POST-Daten statt GET-Requests und eine Authorisierung durch Cookies will) wird teuer.

Hinweis:

Das Beispiel hat (in den Daten selbst) ein paar Mängel in der Datenstruktur, z.B. fehlt ein Datenpunkt für Errors (mit Code und Beschreibungstext) der bei der Auswertung zu beachten sein wird. Ich habe es aber bewusst gewählt um - für den Anfang - was einfaches zu vorzulegen.

** Weitere Beispiel **

Auch wenn ich die serverseitigen Skripte "nicht für zitierfähig" halte und deshalb nicht zeige sollte das hier Deine Phantasie beflügeln.