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.
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
- REST server on esp8266 and esp32: introduction
- REST server on esp8266 and esp32: GET and JSON formatter
- REST server on esp8266 and esp32: POST, PUT, PATCH, DELETE
- REST server on esp8266 and esp32: CORS request, OPTION and GET
- REST server on esp8266 and esp32: CORS request, OPTION and POST