HTTPs REST-API mit dem ESP8266 abfragen

API Okt. 31, 2021
https://my.makesmart.net/topic/232/https-rest-api-mit-dem-esp8266-abfragen

In einem anderem Tutorial habe ich bereits erklärt, wie man einfache HTTP GET-Requests mit einem ESP8266 ausführen und verarbeiten kann. Mit dieser Möglichkeit werden leider keine Anfragen an mit SSL verschlüsselte Verbindungen unterstützt. Aus diesem Grund möchte ich es zum Anlass nehmen, hier ein kurzes Tutorial darüber zu machen, die man eine REST API mit dem ESP8266 abfragen kann, auch wenn die Verbindung mit SSL verschlüsselt ist.

\n

Wichtig zu sagen ist: Die folgende Art und Weise ist nicht sicher, da wir ohne Fingerprint arbeiten und somit nur eine pseudo verschlüsselte Verbindung haben. Aber so können wir die Daten auslesen und verarbeiten.

\n

Da wir mit einer REST API arbeiten, wäre es von Vorteil, wenn ihr euch mein Tutorial zum Thema Arduino IDE - Arbeiten mit JSON Objekten für Einsteiger anschauen würdet. Denn Ziel bei diesem Tutorial ist es, die Antwort des Servers ebenfalls als JSON behandeln zu können. Falls ihr nur schnell zum Ziel kommen wollt, reicht es die ArduinoJSON Library zu installieren.

\n

\"ArduinoJSON

\n
\n

Der Endpoint

\n

Als Endpoint der Anfrage verwenden wir eine Beispiel API von MisterT diese könnt ihr unter https://rip-my.dev/get/mistert abfragen:

\n
{\n  \"name\": \"MisterT\",\n  \"description\": \"Wir stehen für eine gesunde Lebensweise. T \",\n  \"ressources\": [\n    \"/settings\",\n    \"/stats\"\n  ]\n}\n
\n

In dem Array ressources stehen zusätzliche Endpunkte, die ihr callen könnt. Wir haben also insgesamt 3 REST-API Endpoints mit denen wir arbeiten können:

\n
    \n
  1. https://rip-my.dev/get/mistert
  2. \n
  3. https://rip-my.dev/get/mistert/settings
  4. \n
  5. https://rip-my.dev/get/mistert/stats
  6. \n
\n

Ich entscheide mich für dieses Tutorial für den zweiten Endpoint, da wir dort am meisten Daten zum Testen haben.

\n

Der Code

\n

Als Grundlage verwende ich den Code aus meinem Tutorial ESP8266 HTTP-GET Request. Der einzige Unterschied ist, dass wir mit dem folgenden zwei Code-Anpassungen auch auf HTTPs Endpoints zugreifen können:

\n

WiFiClient wifiClient; wird zu: WiFiClientSecure wifiClient;

\n

Zusätzlich, da wir ohne Fingerprint arbeiten, setzen wir den Client dann vor der eigentlichen REST-Abfrage auf insecure:

\n
wifiClient.setInsecure();\n
\n

Und schon kann eine GET-Request an einen HTTPs-Server gesendet werden.

\n
/*\n    HTTPS REST-API GET\n    Basic-Code für GET-Request an einen HTTPS-Server\n    Created by cooper, 2020\n    makesmart.net\n*/\n \n#include <ESP8266WiFi.h>\n#include <ESP8266HTTPClient.h>\n \nHTTPClient sender;\nWiFiClientSecure wifiClient;\n \n// WLAN-Daten\nconst char* ssid = \"WLAN-SSID\";\nconst char* password = \"WLAN-PSK\";\n \n \nvoid setup() {\n  Serial.begin(115200);\n  \n  WiFi.begin(ssid, password);\n \n  while (WiFi.status() != WL_CONNECTED) {\n    delay(200);\n    Serial.print(\".\");\n  }\n \n  Serial.println(\"Mit dem WLAN verbunden!\");\n  Serial.println();\n \n  wifiClient.setInsecure();\n  if (sender.begin(wifiClient, \"https://rip-my.dev/get/mistert/settings\")) {\n    // HTTP-Code der Response speichern\n    int httpCode = sender.GET(); \n    if (httpCode > 0) {\n      // Anfrage wurde gesendet und Server hat geantwortet\n      // Info: Der HTTP-Code für 'OK' ist 200\n      if (httpCode == 200) {\n        // Hier wurden die Daten vom Server empfangen\n        // String vom Webseiteninhalt speichern\n        String payload = sender.getString();\n        // Hier kann mit dem Wert weitergearbeitet werden\n        // ist aber nicht unbedingt notwendig\n        Serial.println(payload);\n      }else{\n        // Falls HTTP-Error\n        Serial.print(\"HTTP-Error: \" +  String(httpCode));\n      }\n    }\n    // Wenn alles abgeschlossen ist, wird die Verbindung wieder beendet\n    sender.end();\n  }else {\n    Serial.printf(\"HTTP-Verbindung konnte nicht hergestellt werden!\");\n  }\n  \n}\n \n \nvoid loop() {\n \n}\n
\n

Das ist mal eine Standard-HTTPs Anfrage an den definierten Server https://rip-my.dev/get/mistert/settings. Als Rückgabewert erhalten wir im seriellen Monitor das JSON Objekt als einfachen String:

\n
{\"adress\":\"192.168.178.27\",\"name\":\"MisterT\",\"default_fill_ml\":220,\"water_value\":4.2,\"additive_value\":10.6,\"standby_color\":\"#fff\",\"strength\":1,\"api_enabled\":true}\n
\n

Diese Response möchten wir jetzt als JSON verarbeiten um sehr leicht auf die einzelnen Keys und Values zugreifen zu können. Das geht wie bereits erwähnt am einfachsten mit der ArduinoJSON Library.

\n

Arbeiten mit der Response als JSON

\n

Zuerst müssen wir in unserem Programm die Arduino JSON Library einbinden:
\n#include <ArduinoJson.h>

\n

Die ganze restliche Magie passiert dann, nachdem wir die Antwort vom Server erhalten haben.
\nDas JSON-Objekt wird im Code bereits als Variable payload gespeichert, dass passiert in der folgenden Zeile:

\n
if (httpCode == 200) {\n        // Hier wurden die Daten vom Server empfangen\n        // String vom Webseiteninhalt speichern\n        String payload = sender.getString();\n        // Hier kann mit dem Wert weitergearbeitet werden\n        // ist aber nicht unbedingt notwendig\n        Serial.println(payload);\n      }\n
\n
{\n  \"adress\": \"192.168.178.27\",\n  \"name\": \"MisterT\",\n  \"default_fill_ml\": 220,\n  \"water_value\": 4.2,\n  \"additive_value\": 10.6,\n  \"standby_color\": \"#fff\",\n  \"strength\": 1,\n  \"api_enabled\": true\n}\n
\n

Die Variable payload kann direkt dafür verwendet werden das JSON Objekt zu deserialisieren.

\n
if (httpCode == 200) {\n        // Hier wurden die Daten vom Server empfangen\n        // String vom Webseiteninhalt speichern\n        String payload = sender.getString();\n\n        // Hier wird ein neuer Buffer mit dem Namen response erzeugt, mit dem wir an die Werte kommen\n        DynamicJsonDocument response(1024);\n        DeserializationError error = deserializeJson(response, payload);\n        if (error)\n          return;\n         \n        // Hier lesen wir die Werte über den Buffer aus\n        String myName = response[\"name\"];\n        int default_fill_ml = response[\"default_fill_ml\"];\n        bool api_enabled = response[\"api_enabled\"];\n        String standby_color = response[\"standby_color\"];\n\n        // Einfache Ausgabe über den seriellen Monitor\n        Serial.println(myName);\n        Serial.println(default_fill_ml);\n        Serial.println(api_enabled);\n        Serial.println(standby_color);\n        \n}\n
\n
MisterT\n220\n1\n#fff\n
\n

So einfach ist, es eine REST API mit dem ESP8266 abzufragen. Wenn du dich mehr für das Thema ArduinoJSON interessierst, dann lohnt sich wie gesagt ein Blick in mein Tutorial Arduino IDE - Arbeiten mit JSON Objekten für Einsteiger. Und für alle die auf der Suche nach einer Copy & Paste Lösung sind, hier nochmal der komplette Code für das deserialisiereneiner REST-API Antwort:

\n
/*\n    HTTPS REST-API GET\n    Basic-Code für GET-Request an einen HTTPS-Server\n    Created by cooper, 2020\n    makesmart.net\n*/\n \n#include <ESP8266WiFi.h>\n#include <ESP8266HTTPClient.h>\n \nHTTPClient sender;\nWiFiClientSecure wifiClient;\n\n#include <ArduinoJson.h>\n \n// WLAN-Daten\nconst char* ssid = \"WLAN-SSID\";\nconst char* password = \"WLAN-PSK\";\n \n \nvoid setup() {\n  Serial.begin(115200);\n  \n  WiFi.begin(ssid, password);\n \n  while (WiFi.status() != WL_CONNECTED) {\n    delay(200);\n    Serial.print(\".\");\n  }\n \n  Serial.println(\"Mit dem WLAN verbunden!\");\n  Serial.println();\n \n  wifiClient.setInsecure();\n  if (sender.begin(wifiClient, \"https://rip-my.dev/get/mistert/settings\")) {\n    // HTTP-Code der Response speichern\n    int httpCode = sender.GET(); \n    if (httpCode > 0) {\n      // Anfrage wurde gesendet und Server hat geantwortet\n      // Info: Der HTTP-Code für 'OK' ist 200\n      if (httpCode == 200) {\n        // Hier wurden die Daten vom Server empfangen\n        // String vom Webseiteninhalt speichern\n        String payload = sender.getString();\n\n        // Hier wird ein neuer Buffer mit dem Namen response erzeugt, mit dem wir an die Werte kommen\n        DynamicJsonDocument response(1024);\n        DeserializationError error = deserializeJson(response, payload);\n        if (error)\n          return;\n         \n        // Hier lesen wir die Werte über den Buffer aus\n        String myName = response[\"name\"];\n        int default_fill_ml = response[\"default_fill_ml\"];\n        bool api_enabled = response[\"api_enabled\"];\n        String standby_color = response[\"standby_color\"];\n\n        // Einfache Ausgabe über den seriellen Monitor\n        Serial.println(myName);\n        Serial.println(default_fill_ml);\n        Serial.println(api_enabled);\n        Serial.println(standby_color);\n        \n      }else{\n        // Falls HTTP-Error\n        Serial.print(\"HTTP-Error: \" +  String(httpCode));\n      }\n    }\n    // Wenn alles abgeschlossen ist, wird die Verbindung wieder beendet\n    sender.end();\n  }else {\n    Serial.printf(\"HTTP-Verbindung konnte nicht hergestellt werden!\");\n  }\n  \n}\n \n \nvoid loop() {\n \n}\n

Community

Die makesmart Community ist der Ort, an dem du deine Ideen mitteilen und deine Erfahrungen austauschen kannst.

Großartig! Das Abonnement wurde erfolgreich abgeschlossen.
Großartig! Schließe als Nächstes die Kaufabwicklung ab, um vollen Zugriff zu erhalten.
Willkommen zurück! Du hast dich erfolgreich angemeldet.
Erfolg! Dein Konto ist vollständig aktiviert, du hast jetzt Zugang zu allen Inhalten.