REST server on esp8266 and esp32: GET and JSON formatter – Part 2

Spread the love

REST server on esp8266 and esp32 GET and JSON formatter
REST server on esp8266 and esp32 GET and JSON formatter

To do a GET you don’t need anything else than the browser, but for more complex operation you must download a program to test your REST API.

I often use WeMos D1 mini, small and simple esp8266.

You can find here WeMos D1 mini - NodeMCU V2 V2.1 V3 - esp01 - esp01 programmer

We are going to download a client like Postman It’s simple and powerful.

When you have download the client click on Import button, select Import From Link and put there this link

https://www.getpostman.com/collections/bbb190822fed3f3b881d

Now you have a new collection of API REST that we use to test our work.

After upload the sketch creted on previous article select getHelloWorld and click Send. If It isn’t working check the name or IP of your device.

Postman HelloWorld example

GET

Naturally, we start with a GET example, this is a more simple verb, It’s used by all browsers to retrieve HTML pages.

For esp32 you must only change this include

#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h>

to

#include <WiFi.h>
#include <WebServer.h>
#include <ESPmDNS.h>

In a REST server this verb is normally used to retrieve data like list of elements or an element.

You can pass parameter via querystring, basically you add couples key, value on the url after a ? and separated via & character.
For example settings?signalStrength=true&chipInfo=true&freeHeap=true .

We are going to do a simple example of a get where you can select what kind of information to show.
I’m going to highlight the code added from previous example.

/*
 * 	Json parametric GET REST response
  *  by Mischianti Renzo <https://mischianti.org>
 *
 *  https://mischianti.org/
 *
 */

#include "Arduino.h"
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h>

const char* ssid = "<YOUR-SSID>";
const char* password = "<YOUR-PASSWD>";

ESP8266WebServer server(80);

// Serving Hello world
void getHelloWord() {
	server.send(200, "text/json", "{\"name\": \"Hello world\"}");
}
// Serving Hello world
void getSettings() {
	String response = "{";

	response+= "\"ip\": \""+WiFi.localIP().toString()+"\"";
	response+= ",\"gw\": \""+WiFi.gatewayIP().toString()+"\"";
	response+= ",\"nm\": \""+WiFi.subnetMask().toString()+"\"";

	if (server.arg("signalStrength")== "true"){
		response+= ",\"signalStrengh\": \""+String(WiFi.RSSI())+"\"";
	}

	if (server.arg("chipInfo")== "true"){
		response+= ",\"chipId\": \""+String(ESP.getChipId())+"\"";
		response+= ",\"flashChipId\": \""+String(ESP.getFlashChipId())+"\"";
		response+= ",\"flashChipSize\": \""+String(ESP.getFlashChipSize())+"\"";
		response+= ",\"flashChipRealSize\": \""+String(ESP.getFlashChipRealSize())+"\"";
	}
	if (server.arg("freeHeap")== "true"){
		response+= ",\"freeHeap\": \""+String(ESP.getFreeHeap())+"\"";
	}
	response+="}";

	server.send(200, "text/json", response);
}

// Define routing
void restServerRouting() {
    server.on("/", HTTP_GET, []() {
    	server.send(200, F("text/html"),
            F("Welcome to the REST Web Server"));
    });
    server.on(F("/helloWorld"), HTTP_GET, getHelloWord);
    server.on(F("/settings"), HTTP_GET, getSettings);
}

// Manage not found URL
void handleNotFound() {
  String message = "File Not Found\n\n";
  message += "URI: ";
  message += server.uri();
  message += "\nMethod: ";
  message += (server.method() == HTTP_GET) ? "GET" : "POST";
  message += "\nArguments: ";
  message += server.args();
  message += "\n";
  for (uint8_t i = 0; i < server.args(); i++) {
    message += " " + server.argName(i) + ": " + server.arg(i) + "\n";
  }
  server.send(404, "text/plain", message);
}

void setup(void) {
  Serial.begin(115200);
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  Serial.println("");

  // Wait for connection
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.print("Connected to ");
  Serial.println(ssid);
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());

  // Activate mDNS this is used to be able to connect to the server
  // with local DNS hostmane esp8266.local
  if (MDNS.begin("esp8266")) {
    Serial.println("MDNS responder started");
  }

  // Set server routing
  restServerRouting();
  // Set not found response
  server.onNotFound(handleNotFound);
  // Start server
  server.begin();
  Serial.println("HTTP server started");
}

void loop(void) {
  server.handleClient();
}

As you can see, I set via querystring 3 parameter and I’m going to check It with arg server method.

	if (server.arg("signalStrength")== "true"){
		response+= ",\"signalStrengh\": \""+String(WiFi.RSSI())+"\"";
	}

If not present the result of arg become a null value so you can omit the parameter:

http://esp8266/settings?freeHeap=true
http://esp8266/settings?signalStrength=false&chipInfo=false&freeHeap=true

As the code is written, the two URLs above have the same result.

JSON Arduino library

Write JSON with String It’s very tedious, so It’s better and more elegant to use a library. Exist a de facto standard library and I write an article “Manage JSON file with Arduino and esp8266” on how to use It.

So we are going to rewrite the sketch.

/*
 * 	Json parametric GET REST response with ArduinoJSON library
  *  by Mischianti Renzo <https://mischianti.org>
 *
 *  https://mischianti.org/
 *
 */

#include "Arduino.h"
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h>
#include <ArduinoJson.h>

const char* ssid = "<YOUR-SSID>";
const char* password = "<YOUR-PASSWD>";

ESP8266WebServer server(80);

// Serving Hello world
void getHelloWord() {
	  DynamicJsonDocument doc(512);
	  doc["name"] = "Hello world";

	  Serial.print(F("Stream..."));
	  String buf;
	  serializeJson(doc, buf);
	  server.send(200, "application/json", buf);
	  Serial.print(F("done."));
}
// Serving Hello world
void getSettings() {
	  // Allocate a temporary JsonDocument
	  // Don't forget to change the capacity to match your requirements.
	  // Use arduinojson.org/v6/assistant to compute the capacity.
	//  StaticJsonDocument<512> doc;
	  // You can use DynamicJsonDocument as well
	  DynamicJsonDocument doc(512);

	  doc["ip"] = WiFi.localIP().toString();
	  doc["gw"] = WiFi.gatewayIP().toString();
	  doc["nm"] = WiFi.subnetMask().toString();

	  if (server.arg("signalStrength")== "true"){
		  doc["signalStrengh"] = WiFi.RSSI();
	  }

	  if (server.arg("chipInfo")== "true"){
		  doc["chipId"] = ESP.getChipId();
		  doc["flashChipId"] = ESP.getFlashChipId();
		  doc["flashChipSize"] = ESP.getFlashChipSize();
		  doc["flashChipRealSize"] = ESP.getFlashChipRealSize();
	  }
	  if (server.arg("freeHeap")== "true"){
		  doc["freeHeap"] = ESP.getFreeHeap();
	  }

	  Serial.print(F("Stream..."));
	  String buf;
	  serializeJson(doc, buf);
	  server.send(200, F("application/json"), buf);
	  Serial.print(F("done."));
}

// Define routing
void restServerRouting() {
    server.on("/", HTTP_GET, []() {
    	server.send(200, F("text/html"),
            F("Welcome to the REST Web Server"));
    });
    server.on(F("/helloWorld"), HTTP_GET, getHelloWord);
    server.on(F("/settings"), HTTP_GET, getSettings);
}

// Manage not found URL
void handleNotFound() {
  String message = "File Not Found\n\n";
  message += "URI: ";
  message += server.uri();
  message += "\nMethod: ";
  message += (server.method() == HTTP_GET) ? "GET" : "POST";
  message += "\nArguments: ";
  message += server.args();
  message += "\n";
  for (uint8_t i = 0; i < server.args(); i++) {
    message += " " + server.argName(i) + ": " + server.arg(i) + "\n";
  }
  server.send(404, "text/plain", message);
}

void setup(void) {
  Serial.begin(115200);
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  Serial.println("");

  // Wait for connection
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.print("Connected to ");
  Serial.println(ssid);
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());

  // Activate mDNS this is used to be able to connect to the server
  // with local DNS hostmane esp8266.local
  if (MDNS.begin("esp8266")) {
    Serial.println("MDNS responder started");
  }

  // Set server routing
  restServerRouting();
  // Set not found response
  server.onNotFound(handleNotFound);
  // Start server
  server.begin();
  Serial.println("HTTP server started");
}

void loop(void) {
  server.handleClient();
}

With this library It’s become more readable, but remember, though Arduino JSON is a fantastic library It introduce some “problem” like memory usage to create the JSON file.

The core part of JSON management is in this code

	  DynamicJsonDocument doc(512);

	  doc["ip"] = WiFi.localIP().toString();
	  doc["gw"] = WiFi.gatewayIP().toString();
	  doc["nm"] = WiFi.subnetMask().toString();

	  if (server.arg("signalStrength")== "true"){
		  doc["signalStrengh"] = WiFi.RSSI();
	  }

	  if (server.arg("chipInfo")== "true"){
		  doc["chipId"] = ESP.getChipId();
		  doc["flashChipId"] = ESP.getFlashChipId();
		  doc["flashChipSize"] = ESP.getFlashChipSize();
		  doc["flashChipRealSize"] = ESP.getFlashChipRealSize();
	  }
	  if (server.arg("freeHeap")== "true"){
		  doc["freeHeap"] = ESP.getFreeHeap();
	  }

	  Serial.print(F("Stream..."));
	  String buf;
	  serializeJson(doc, buf);
	  server.send(200, F("application/json"), buf);

As you can see the command serializeJson(doc, buf); copy the JSON on String variable, than server.send(200, F("application/json"), buf); return the content of the file to the client.

Here the result

{
    "ip": "192.168.1.127",
    "gw": "192.168.1.1",
    "nm": "255.255.255.0",
    "signalStrengh": -37,
    "chipId": 10892005,
    "flashChipId": 1458376,
    "flashChipSize": 4194304,
    "flashChipRealSize": 4194304,
    "freeHeap": 41648
}

Thanks

  1. REST server on esp8266 and esp32: introduction
  2. REST server on esp8266 and esp32: GET and JSON formatter
  3. REST server on esp8266 and esp32: POST, PUT, PATCH, DELETE
  4. REST server on esp8266 and esp32: CORS request, OPTION and GET
  5. REST server on esp8266 and esp32: CORS request, OPTION and POST

Spread the love

4 Responses

  1. Mathias says:

    For some reason when I switch to ESP32 and change the .h files
    I get the error: ‘class EspClass’ has no member named ‘getChipId’

    for example : doc[“chipId”] = ESP.getChipId(); the ESP isnt orange anymore do I have to change this to something else ?

    • Hi Mathias,
      I forgot to write that you must change that part also, I write It in the part 4, tomorrow i’m going to copy here also.
      Now check the part 4 and change like that.

      Bye Renzo

Leave a Reply

Your email address will not be published. Required fields are marked *